這道題的確比較難想,首先我們知道圖比較小,有可能是枚舉,那麼該如何枚舉呢???
你可以發現,我們只要把第一排定了,並且保證第一排不準動,那麼答案就定了
也就是說,我們首先用二進制枚舉,枚舉第一行需要翻轉的,然後讓第一行不準再翻轉,後面的翻轉只能在第二行進行,那麼第二翻轉的實際上是定好了的,然後因爲定好了,所以不能翻轉,那麼第二行也定了,我們要改變第二行,只能通過第三行,最後判斷一下最後一位是不是0就好了,做法的話,可以把每一行用一個數字保存,然後進行異或操作,對某位的1或者0進行操作,或者笨一點開二維數組。
#include <bits/stdc++.h> using namespace std; char str[10][10]; const int INF = 0x3f3f3f3f; int main(){ int t; scanf("%d",&t); char s[10][10]; int a[5]; while(t--){ memset(a,0,sizeof(a)); for (int i=0;i<5;i++){ scanf("%s",s[i]); int ss=16; for (int j=0;j<5;j++){ if (s[i][j]=='0'){ a[i]+=ss; } ss=ss/2; } } int b[5]; int ans=INF; for (int i=0;i<(1<<5)-1;i++){ for (int j=0;j<5;j++){ b[j]=a[j]; } int cnt=0; for (int j=0;j<5;j++){ if((i>>j)&1){ cnt++; b[0]=b[0]^(1<<j); b[1]=b[1]^(1<<j); if (j+1<5){ b[0]=b[0]^(1<<(j+1)); } if (j-1>=0){ b[0]=b[0]^(1<<(j-1)); } } } for (int j=1;j<5;j++){ for (int k=0;k<5;k++){ if((b[j-1]>>k)&1){ b[j-1]=b[j-1]^(1<<k); b[j]=b[j]^(1<<k); cnt++; if (k+1<5){ b[j]=b[j]^(1<<(k+1)); } if (k-1>=0){ b[j]=b[j]^(1<<(k-1)); } if (j+1<5){ b[j+1]=b[j+1]^(1<<(k)); } } } } int flag=0; for (int j=0;j<5;j++){ if (b[j]!=0){ flag=1; break; } } if (flag==0){ ans=min(ans,cnt); } } if (ans<=6){ printf("%d\n",ans); }else { printf("-1\n"); } } return 0; }