今天因为昨天作死写替罪羊树被教练吵了......我再也不好高骛远了QAQ。
今天一如既往的进行了考试,今天的题没有原题,除了一道学长出的教练忘掉的题之外,其他的题都是第一次见,今天也是我写暴力写的题占比最大的一天(因为正解思路想不到),说明还是得练呀,水平还是不高,今天我们四个人中三个人的名次都相对进步了,只有我退步了一名......
这道题的数只有4*4=16,应该可以想到状压dp,但是去压哪一个就是我们所思考的问题了,我刚开始的时候想的是去压每一个位置是黑面还是白面,但是我们的转移就不好进行,因为后面的处理结果可能正是前面的运算所需要的,即有后效性,这是不符合dp的使用原则的,于是我们换一种思路,来用状压表示是否对原状态的几位进行反转操作,这样我们前后的计算就互不影响,可以进行dp的,其实这道题还是挺简单的,虽然我只有50pts
1 #include <bits/stdc++.h> 2 const int maxn=4+5,Inf=1<<16; 3 char str[maxn][maxn]; 4 int ans=Inf; 5 char tmp[maxn][maxn]; 6 void flip(char &ch){ 7 if(ch=='w')ch='b'; 8 else if(ch=='b')ch='w'; 9 } 10 int cnt; 11 void press(int x,int y){ 12 cnt++; 13 flip(tmp[x][y]); 14 flip(tmp[x][y+1]);flip(tmp[x][y-1]); 15 flip(tmp[x-1][y]);flip(tmp[x+1][y]); 16 } 17 void calc(int x,char ch){ 18 memcpy(tmp,str,sizeof(str)); 19 cnt=0; 20 for(int i=1;i<=4;i++) 21 if(x & (1<<(i-1))) 22 press(1,i); 23 for(int i=2;i<=4;++i){ 24 for(int j=1;j<=4;++j){ 25 if(tmp[i-1][j]!=ch) 26 press(i,j); 27 } 28 } 29 for(int i=1;i<=4;++i) 30 if(tmp[4][i]!=ch)return; 31 ans=std::min(ans,cnt); 32 33 } 34 void Solve(){ 35 for(int i=1;i<=4;++i) 36 scanf("%s",str[i]+1); 37 for(int i=0;i<=15;++i){ 38 calc(i,'w'); 39 calc(i,'b'); 40 } 41 if(ans==Inf) 42 printf("Impossible\n"); 43 else 44 printf("%d\n",ans); 45 } 46 int main(){ 47 Solve(); 48 return 0; 49 }