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;
}