http://poj.org/problem?id=1753
4*4方格的翻转棋,翻转一个,他四周的棋子也都翻转。问最小多少步一方赢。
BFS的基本题,有意思的是涉及到了位运算,,,恩恩 ,,灰常神奇!!
这里有灰常细致的讲解http://blog.csdn.net/lyy289065406/article/details/6642595 膜拜~
//把矩阵看成一个16进制数
//每一行代表16进制数的一个字母(或数字),而每一个字母(或数字)又恰由4个二进制位数字0和1组成
//因此一个4x4矩阵是由16位0和1构成,是从 第0位 到 第15位
//如矩阵
// * * * * 从右到左分别为第 0, 1, 2, 3位
// % % % % 从右到左分别为第 4, 5, 6, 7位
// # # # # 从右到左分别为第 8, 9,10,11位
// @ @ @ @ 从右到左分别为第12,13,14,15位
//代表16进制数
// @@@@ #### %%%% ****
// 15 ← 0
// 将一个int的某位 取反 用该int与(0x1<<i)进行^操作。
贴代码:
#include <cstdio>
#include <queue>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int maxn=0xffff;
char map[4][4];
int step;
int hehe=0;
int vis[maxn+1];
struct fuck
{
int hehe;
int step;
};
int bfs()
{
queue <fuck> q;
fuck now,next;
now.hehe=hehe;
now.step=0;
q.push(now);
vis[hehe]=1;
while(!q.empty()){
now=q.front();
q.pop();
if(now.hehe==maxn||now.hehe==0) //全是白的或者全是黑的~
return now.step;
for (int i = 0; i < 16; ++i)
{
int heihei=now.hehe;
heihei=heihei^(1<<i); //把右边数第i位(从0开始)翻转
if(i>3)//翻上面的
heihei=heihei^(1<<(i-4));
if(i<12)//翻转下面
heihei=heihei^(1<<(i+4));
if(i%4!=0)//right
heihei=heihei^(1<<(i-1));
if(i%4!=3)//left
heihei=heihei^(1<<(i+1));
next.hehe=heihei;
next.step=now.step+1;
if(vis[heihei]==0){
vis[heihei]=1;
q.push(next);
}
}
}
while(!q.empty())
q.pop();
return -1;
}
int main()
{
//freopen("input.txt","r",stdin);
hehe=0;
for(int i=0;i<4;i++){ //把地图放到hehe里
gets(map[i]);
for(int j=0;j<4;j++){ //把地图上下翻转了90°,但是都一样,无碍
if(map[i][j]=='b')
hehe=(hehe<<1)+1;
else hehe=hehe<<1;
}
}
memset(vis,0,sizeof(vis));
step=bfs();
if(step==-1)
printf("Impossible\n");
else printf("%d\n",step );
return 0;
}