【POJ 1753】Flip Game
2015-06-09 01:44
489 查看
【POJ 1753】Flip Game
二进制+(BFS)暴力枚举
原本用二位字符数组存 发现遍历困难 并且翻动棋子也难办 后来想到一维线性
下标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
在图中即为
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
预处理出一个数组进行翻转 后来又发现预处理难办 灵光一现 由于只有黑白两色 可用1 0标记 看到1 0想到的当然就是二进制了 并且又做成了个线性 刚好16位二进制 一切迎刃而解 翻转可用二进制运算^(异或) 上代码
二进制+(BFS)暴力枚举
原本用二位字符数组存 发现遍历困难 并且翻动棋子也难办 后来想到一维线性
下标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
在图中即为
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
预处理出一个数组进行翻转 后来又发现预处理难办 灵光一现 由于只有黑白两色 可用1 0标记 看到1 0想到的当然就是二进制了 并且又做成了个线性 刚好16位二进制 一切迎刃而解 翻转可用二进制运算^(异或) 上代码
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #define INF 0x3f3f3f3f using namespace std; int ms; int step[65536]; int dir[32]; bool vis[65536]; int tp; int GetNum(char *str)//黑1 白 0 { int i,x = 0; for(i = 1; i <= 16; ++i) { x <<= 1; x += (str[i] == 'b')? 1: 0; } return x; } //void PrintNum(int x) //{ // int i = 1; // while(x) // { // if(x&1) printf("1 "); // else printf("0 "); // x >>= 1; // if(!(i%4)) printf("\n"); // ++i; // } // for(; i <= 16; ++i) // { // printf("0 "); // if(!(i%4)) printf("\n"); // } // printf("\n\n"); //} void Memset(char *str,char a) { int i,j; for(i = 1; i <= 16; ++i) str[i] = a; } void Getdir() { tp = 0; char str[49]; int i,j; Memset(str,'w'); for(i = 16; i >= 1; --i) { str[i+1] = str[i+5] = str[i+2]= 'w'; if(i-3 > 0) str[i-3] = 'w'; str[i] = str[i+4] = 'b'; if(i%4) str[i+1] = 'b'; if((i-1)%4) str[i-1] = 'b'; if(i-4 > 0) str[i-4] = 'b'; dir[tp++] = GetNum(str); } } void Bfs() { memset(step,INF,sizeof(step)); memset(vis,0,sizeof(vis)); step[ms] = 0; int i,x,v; queue <int> q; q.push(ms); while(!q.empty()) { x = q.front(); q.pop(); vis[x] = 0; for(i = 0; i < tp; ++i) { v = x^dir[i]; if(step[v] > step[x]+1) { step[v] = step[x]+1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } } } int main() { //freopen("in.txt","r",stdin); char str[18]; int i,j,x; for(i = 1; i < 17; i += 4) { scanf("%s",str+i); } ms = GetNum(str); Getdir(); // for(i = 0; i < tp; ++i) // PrintNum(dir[i]); if(ms == 0 || ms == 65535) printf("0\n"); else { Bfs(); x = min(step[0],step[65535]); if(x == INF) printf("Impossible\n"); else printf("%d\n",x); } return 0; }
相关文章推荐
- LeetCode | Palindrome Number
- linux fdisk 下磁盘查看命令分享很简单
- Codeforces Round #306 (Div. 2) (ABCE题解)
- OpenLayers学习笔记5——使用jQuery UI实现查询并标注(UI篇)
- Java NIO使用及原理分析 (四)
- [Swust OJ 1094]--中位数(巧用set,堆排序)
- shutdown reboot init 重启命令 关机命令 简单介绍
- HDU 5266 pog loves szh III ( LCA + SegTree||RMQ )
- qt大全(连接)
- EXCEL文件行交替背景色设置
- HDU 5265 pog loves szh II
- win8中如何设定editplus为txt默认打开程序
- 循环顺序队列2——使用标示位判断队满或空
- EXCEL内的字符比较公式
- 2015区域赛起航
- 菜鸟学Android笔记(二十六):Response数据输出
- APP Launchimage软件启动图片
- 黑马程序员_多线程间通信
- UVA 10635 Prince and Princess 最长公共子序列(nlongn)
- Rectangle Area