题目链接:wikioi 1004
解题思路:
宽搜,状态判重用哈希+set
代码:
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int a[4][4],num,cnt;
node(int num=0,int cnt=0):num(num),cnt(cnt){}
};
int xx[]={-1,1,0,0};
int yy[]={0,0,-1,1};
bool check(node tmp)
{
int flag;
for(int i=0;i<4;i++)
{
flag=1;
for(int j=1;j<4;j++)
if(tmp.a[i][0]!=tmp.a[i][j])
flag=0;
if(flag) return 1;
}
for(int i=0;i<4;i++)
{
flag=1;
for(int j=1;j<4;j++)
if(tmp.a[0][i]!=tmp.a[j][i])
flag=0;
if(flag) return 1;
}
flag=1;
for(int i=0;i<4;i++)
if(tmp.a[i][i]!=tmp.a[0][0])
flag=0;
if(flag) return 1;
flag=1;
for(int i=0;i<4;i++)
if(tmp.a[i][4-i-1]!=tmp.a[0][3])
flag=0;
if(flag) return 1;
return 0;
}
int cal(node tmp){
int cnt=0,sum=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
sum=sum*3+tmp.a[i][j];
return sum;
}
set<int> pnt[2];
node head,tmp;
queue<node> q;
int main()
{
char st[10];
for(int i=0;i<4;i++)
{
scanf("%s",st);
for(int j=0;j<4;j++)
{
if(st[j]=='B')
head.a[i][j]=1;
if(st[j]=='W')
head.a[i][j]=2;
if(st[j]=='O')
head.a[i][j]=0;
}
}
head.cnt=0;
head.num=0;
pnt[head.num].insert(cal(head));
q.push(head);
head.num=1;
pnt[head.num].insert(cal(head));
q.push(head);
int x,y;
while(!q.empty())
{
head=q.front();
q.pop();
if(check(head))
break;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(!head.a[i][j])
{
for(int k=0;k<4;k++)
{
x=i+xx[k],y=j+yy[k];
if(x>=0&&x<4&&y>=0&&y<4
&&1+head.num==head.a[x][y])
{
tmp=head;
tmp.cnt=head.cnt+1,tmp.num=1-head.num;
swap(tmp.a[x][y],tmp.a[i][j]);
if(!pnt[tmp.num].count(cal(tmp)))
{
pnt[tmp.num].insert(cal(tmp));
q.push(tmp);
}
}
}
}
}
}
}
printf("%d\n",head.cnt);
return 0;
}