标签:using play nbsp problem 十进制 处理 rip 标记 font
题目网址:http://poj.org/problem?id=1753
题目:
Description
Input
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
思路:
棋盘只有4*4即16格,我们把这16格的白棋黑棋状态分别用1,0表示,就可以用十进制的0——(2^15-1即65535)表示所有情况。利用0^1=1,1^1=0,0^0=0即无论0,1与0做^运算都等于其本身,无论0,1与1做^运算都等于另一个数的特性,我们将翻转棋子操作,变成将选定棋子和四周的棋子的状态^1,其余棋子状态^0。再用bfs进行搜索,用vis数组标记当前棋盘情况是否出现过,未出现则将当前情况入队,反之则不入。
代码:
1 #include <cstdio> 2 #include <vector> 3 #include <queue> 4 using namespace std; 5 int vis[70000]; 6 int mp[16]={//预处理,事先算出翻转16个棋子 分别对应的"^"操作数 7 51200,58368,29184,12544, 8 35968,20032,10016,4880, 9 2248,1252,626,305, 10 140,78,39,19 11 }; 12 char chess[5][5]; 13 vector<int>v; 14 queue<int>q; 15 int change(){//将棋盘的初始状态压缩 16 int x=v[0]; 17 for (int i=1; i<v.size(); i++) { 18 x=(x<<1)+v[i]; 19 } 20 return x; 21 } 22 int bfs(int v){ 23 vis[v]=1; 24 q.push(v); 25 while (!q.empty()) { 26 int x=q.front();q.pop(); 27 if(x==0 || x== 65535) return vis[x]-1;//vis数组保存的是当前步数+1 28 for (int i=0; i<16; i++) {//分别翻转16个棋子 29 int xt=x^mp[i]; 30 if(vis[xt]) continue; 31 vis[xt]=vis[x]+1; 32 q.push(xt); 33 } 34 } 35 return -1; 36 } 37 int main(){ 38 for (int i=0; i<4; i++) { 39 gets(chess[i]); 40 for (int j=0; j<4; j++) { 41 if(chess[i][j]==‘b‘) v.push_back(1); 42 else v.push_back(0); 43 } 44 } 45 int x=bfs(change()); 46 if(x!=-1) printf("%d\n",x); 47 else printf("Impossible\n"); 48 return 0; 49 }
标签:using play nbsp problem 十进制 处理 rip 标记 font
原文地址:http://www.cnblogs.com/uniles/p/7216966.html