POJ_1753
来源:互联网 发布:mac的办公软件 编辑:程序博客网 时间:2024/05/01 03:11
解题思路:关键是要理解,每个格子只有两种状态,而且最终翻转方法与格子被翻转的次序无关。
1. 位运算+BFS / BFS
2. 枚举:只要有一种枚举不满足,则其他枚举也不满足,反之,只要有一种枚举满足,则所有枚举都满足,因为同一个方块反转两次,整体不变,猜测所有的可行解都是可以相互转换,并且都始于全黑/白,终于全黑/白。
http://poj.org/showmessage?message_id=165833(0ms,用进制枚举的方法很好,但是整体的方法不能确定是否正确,因为这题只有一个case,但是思路很好)。
3. 高斯消元法
代码:
1. ^的使用, 两次^等于本身,和翻转一样。
2. 每个棋子只有两种状态, 共2 ^ 16种, 可以用一个int表示,即状态压缩,然后BFS枚举所有的状态。
3. Flip()是对压缩状态的翻转+4, -4, +1, -1
4. 在BFS的时候,队列中保存状态和层数的二元组,要比在队列中每层压入哨兵高效和简单。
5. 使用位移直接input到压缩状态。
//280k 79ms#include <stdio.h>#include <stdlib.h>#include <string.h>#include <queue>#include <algorithm>using namespace std;int Flip(int cur, int pos) { cur ^= (1 << pos); if (pos + 4 < 16) cur ^= (1 << pos + 4); if (pos - 4 >= 0) cur ^= (1 << pos - 4); if (pos % 4) cur ^= (1 << pos - 1); if (pos % 4 != 3) cur ^= (1 << pos + 1); return cur;}int BFS(int board) { if (board == 65535 || board == 0) return 0; queue<pair<int, int> > q; bool visit[65536]; memset(visit, 0, sizeof(visit)); q.push(make_pair(board, 0)); visit[board]; while (q.size()) { pair<int, int> pii = q.front(); q.pop(); int cur = pii.first; for (int i = 0; i < 16; ++i) { int next = Flip(cur, i); if (next == 65535 || next == 0) return pii.second + 1; if (visit[next]) continue; q.push(make_pair(next, pii.second + 1)); visit[next] = 1; } } return -1;}int main() { char piece; int board = 0; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { piece = getchar(); if (piece == 'b') board |= (1 << (i * 4 + j)); } getchar(); } int res = BFS(board); if (res == -1) printf("Impossible"); else printf("%d", res); return 0;}
- poj_1753
- poj_1753
- POJ_1753
- poj_1753
- poj_1753
- POJ_1753
- poj_1753 递归+枚举
- Flip Game(POJ_1753)
- Flip Game(POJ_1753)
- POJ_1753(位运算)
- Poj_1753 Flip Game(状态压缩,bfs)
- poj_1753 Flip Game(dfs+枚举)/(bfs+位运算)
- 【总结】关于在Android中如何使用字符串数组String[]
- Python的pyc和pyo文件
- javascript知识结构
- py文件编译为pyc
- 详细介绍Java内存泄露原因
- POJ_1753
- 去掉字符串中的数字
- Java内存泄露小例子
- LeetCode题解:3sum closest
- 用位运算生成分形
- 手势、画图、截图
- Debian 7 下搭建 IPSEC + L2TP VPN 服务器
- Java中的Set,List,Map的区别
- Linux内核访问I/O资源的方法:动态映射(ioremap)和静态映射(map_desc)