poj1753Flip Game之 广搜解法+暴搜解法
来源:互联网 发布:python 登录界面 编辑:程序博客网 时间:2024/05/20 09:07
题意:每次翻一个棋子会带动周围棋子翻面,问需要的最小翻棋次数使得棋盘颜色一致。
分析:棋盘上有16个棋子,分别对应二进制数的16-1位,用1表示black或white,这样一个整数value就可以表示一种棋盘状态。
每次翻棋可以用异或^进行,然后在value的基础上进行搜索。
/*输入方式一*/// int k = 0;// for (int i = 0; i < 4; ++i){// for (int j = 0; j < 4; ++j){// cin >> atlas[i][j];// if(atlas[i][j] == 'b') value += 1<<k;// k++;// }// }/*输入方式二*/// for (int i = 0; i < 4; ++i){// for (int j = 0; j < 4; ++j){// cin >> atlas[i][j];// value <<= 1;// if(atlas[i][j] == 'b') value += 1;// }// }/*输入方式三*/// for (int i = 0; i < 16; ++i)// {// char c;// cin >> c;// if(c == 'b') value += judge[i];// }
解法一:暴力搜索
/**********************************暴力搜索法每个棋子要么翻要么不翻,总共有2^16 = 65536种可能性;假设每一位用1表示翻棋,则可以用0-65535表示这65536种可能性;遍历所有翻棋方法,找到使当前棋局变为全白或全黑的方法并保存步数;找到其中最小步数。 **********************************/#include <cstdio> #include <iostream> using namespace std; char atlas[5][5];//1表示黑棋int change[20] = { 0xc800,0xe400,0x7200,0x3100, 0x8c80,0x4e40,0x2720,0x1310, 0x08c8,0x04e4,0x0272,0x0131, 0x008c,0x004e,0x0027,0x0013};int judge[20] = { 0x8000,0x4000,0x2000,0x1000, 0x0800,0x0400,0x0200,0x0100, 0x0080,0x0040,0x0020,0x0010, 0x0008,0x0004,0x0002,0x0001};int value;int step;int main() { value = 0; step = 17; int k = 0; for (int i = 0; i < 4; ++i){ for (int j = 0; j < 4; ++j){ cin >> atlas[i][j]; if(atlas[i][j] == 'b') value += 1<<k; k++; } } for (int i = 0; i < 65536; ++i) {//65536种翻棋方法 int tvalue = value; int tstep = 0; for (int j = 0; j < 16; ++j){//依次判断16个棋子是否翻动 if (i & judge[j]){ tvalue ^= change[j]; tstep++; } } if (tvalue == 0 || tvalue == 65535) step = min(step,tstep); } if(step < 17) cout << step << endl; else cout << "Impossible" << endl; return 0; }
解法二:宽度优先搜索
/**********************************广度优先搜索首先进行棋盘的状态压缩,保存棋盘;然后对棋盘进行广度优先搜索;要注意,广搜入口有16个,但是由于翻棋顺序对于棋盘结果不影响,所以翻棋状态只有2^16 = 65536种。 **********************************/#include <iostream> #include <cstring>#include <queue> using namespace std; int change[20] = {//16个翻棋方式 0xc800,0xe400,0x7200,0x3100, 0x8c80,0x4e40,0x2720,0x1310, 0x08c8,0x04e4,0x0272,0x0131, 0x008c,0x004e,0x0027,0x0013};int value;int step;int visit[65536];typedef pair<int,int> p;queue <p> qu;void bfs(){ while(!qu.empty()){ p f = qu.front();qu.pop(); for (int i = 0; i < 16; ++i){ int tf = f.first^change[i]; int tstep = f.second + 1; if(visit[tf]) continue; if(tf == 0 || tf == 65535){ step = tstep;return; } visit[tf] = 1; qu.push(make_pair(tf,tstep)); } }}int main() { value = 0; step = 17; for (int i = 0; i < 4; ++i){ for (int j = 0; j < 4; ++j){ char c; cin >> c; value <<= 1; if(c == 'b') value += 1; } } if(value == 0 || value == 65535) { cout << "0" << endl;return 0; } qu.push(make_pair(value,0)); memset(visit,0,sizeof(visit)); visit[value] = 1; bfs(); if(step < 17) cout << step << endl; else cout << "Impossible" << endl; return 0; }
阅读全文
0 0
- poj1753Flip Game之 广搜解法+暴搜解法
- 独轮车广搜解法
- ccf 201403-4 无线网络 (广搜解法)
- POJ 3984 迷宫问题 广搜迷宫解法
- POJ1753Flip Game
- poj1753Flip Game
- poj1753Flip Game
- POJ1753Flip Game
- poj1753Flip Game
- Nim Game问题及解法
- Jump Game问题及解法
- Elimination Game问题及解法
- Baseball Game问题及解法
- poj1753Flip Game(DFS+枚举)
- poj1753_Flip Game(广搜)
- hdu2216 Game III 【广搜】
- 迷宫解法之栈/队列的解法
- 最大公约数之递归解法
- 【实战】qq账户和密码的发送器
- 生活小记36
- 括号配对问题//正在奋斗的弱弱的程序员
- CSS 经典导航
- JZOJ 5436. 【NOIP2017提高A组集训10.30】Group
- poj1753Flip Game之 广搜解法+暴搜解法
- 聚类之DBSCAN学习
- 国际化
- 【HDU
- sublime配置C语言和c++编译环境
- Redis有序集合
- 接口文档
- 【Opencv】树莓派配置Opencv 3.2 + Raspicam (一) 系统初始配置 5种方法访问树莓派
- 如何写论文的“引言”部分