POJ 1753.Flip Game

来源:互联网 发布:复杂网络社区发现研究 编辑:程序博客网 时间:2024/06/02 03:13

题目:http://poj.org/problem?id=1753

AC代码(C++):

#include <iostream>#include <algorithm>#include <stdio.h>#include <vector>#include <queue>#include <math.h>#include <string.h>using namespace std;struct BOARD{char p[4][4];int step;};void boardToNum(BOARD b, int &i, int &j, int &k, int &l){int r[4] = {0,0,0,0};for(int ii = 0; ii < 4; ii++){for(int jj = 0; jj < 4; jj++){if(b.p[ii][jj] == 'w'){int tmp = 1;for(int kk = 0; kk < jj; kk++)tmp*=2;r[ii] += tmp;}}}i=r[0];j=r[1];k=r[2];l=r[3];}bool isSuccess(BOARD b){char w = b.p[0][0];for(int i = 0; i < 4; i++){for(int j = 0; j < 4; j++){if(b.p[i][j]!=w)return false;}}return true;}void bfs(BOARD I){queue<BOARD> q;bool vis[16][16][16][16];memset(vis, false, sizeof(vis));q.push(I);int aa,bb,cc,dd;boardToNum(I,aa,bb,cc,dd);vis[aa][bb][cc][dd] = true;BOARD node;bool flag = false;while (!q.empty()) {node = q.front();q.pop();if(isSuccess(node)){cout<<node.step;flag = true;break;}for(int i = 0; i < 4; i++){for(int j = 0; j < 4; j++){BOARD next = node;next.step++;if(next.p[i][j] == 'b')next.p[i][j] = 'w';else next.p[i][j] = 'b';if(i+1<4){if(next.p[i+1][j] == 'b')next.p[i+1][j] = 'w';else next.p[i+1][j] = 'b';}if(i-1>=0){if(next.p[i-1][j] == 'b')next.p[i-1][j] = 'w';else next.p[i-1][j] = 'b';}if(j+1<4){if(next.p[i][j+1] == 'b')next.p[i][j+1] = 'w';else next.p[i][j+1] = 'b';}if(j-1>=0){if(next.p[i][j-1] == 'b')next.p[i][j-1] = 'w';else next.p[i][j-1] = 'b';}int a,b,c,d;boardToNum(next,a,b,c,d);if(vis[a][b][c][d]==false){q.push(next);vis[a][b][c][d]=true;}}}}if(flag==false)cout<<"Impossible";}int main(){BOARD I;//输入for(int i = 0; i < 4; i++)for(int j = 0; j < 4; j++)cin>>I.p[i][j];I.step = 0;//遍历bfs(I);}
总结:简单的搜索题, 根据题目性质选择广搜, 找到答案后输出, 若未找到答案则输出Impossible. 稍微有点难的地方是怎么实现visited数组, 我是将棋盘状态编码, 一行的状态有16种可能性, 一共4行, 所以编码后visited数组可以表示成bool vis[16][16][16][16], 自己再写个编码函数即可.