20174/12/8
太懒了,那几个比赛补完后就不知道刷什么题了。算法也不知道学什么。。
就开个系列吧。-。-跟着前人的脚步走。
PS:
12点多开始撸这第一题。。
第一眼看错题意 :Each round you flip 3 to 5 pieces 。。还以为只能翻转3-5个棋子。。。托托的写了发暴力。。
神奇的是样例过了0 0(暴力代码已经出成题目,请党和人民放心)
然后.....想到用位来表示状态,之后!-。-继续写暴力。嘎嘎。
用位来表示棋盘的状态,就 65536种状态,弄个vis,遍历过的不在遍历。然后 1 - 16位挨个翻转,LOL。
直到找到全黑或者全白,(1表示白0表示黑,全黑0->0000000000000000,全白 65535 -> 1111111111111111)
然后每次按题意翻转0 0,把该改变的值改掉,0>-1,1->0. 为了方便得出min的步数,用了bfs来转移状态。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int vis[70000];
int ct[70000];
char s[5][5];
int flag;
int temp[4][4]={
1,2,4,8,
16,32,64,128,
256,512,1024,2048,
4096,8192,16384,32768
};
queue<int>q;
int wk(int x,int y,int sum)
{
sum^=temp[x][y];
if(x-1>=0)sum^=temp[x-1][y];
if(y-1>=0)sum^=temp[x][y-1];
if(x+1<4)sum^=temp[x+1][y];
if(y+1<4)sum^=temp[x][y+1];
return sum;
}
void bfs(int x)
{
if(vis[x])return;
vis[x]= 1;
for(int i = 0;i < 4; i++)
for(int j = 0;j < 4; j++)
{
int num = wk(i,j,x);
ct[num] = ct[x]+1;
if(num==0 || num == 65535)
{
printf("%d\n",ct[num]);
flag = 0;
return ;
}
if(!vis[num])
q.push(num);
}
return ;
}
int main()
{
while(~scanf("%s",s[0]))
{
flag =1;
memset(vis,0,sizeof(vis));
memset(ct,0,sizeof(ct));
for(int i =1;i < 4; i++)
scanf("%s",s[i]);
int sum = 0;
for(int i = 0;i < 4; i++)
for(int j = 0;j < 4; j++)
{
if(s[i][j]=='w')sum+=temp[i][j];
}
if(sum==0||sum==65535)
{
printf("0\n");
continue ;
}
ct[sum] = 0;
q.push(sum);
while(!q.empty())
{
int n = q.front();
q.pop();
if(flag)
{
bfs(n);
}
}
if(flag)
{
printf("Impossible\n");
}
}
return 0;
}