uva 11464 偶數矩陣 (二進位制表示法)
阿新 • • 發佈:2018-12-11
題目大意:有一個N*N的01矩陣,你的任務是把儘量少的0變成1,(但不能將1變成0)以使得每個元素的上下左右的元素(若存在)均為偶數。
思路 : 如果暴力列舉每一個位置的話時間複雜度為 2 的255 次方,肯定不行 。但是如果只列舉第一行,其他下面幾行都能夠通過
上邊的來固定是0還是1。時間複雜度就是 2的15次方 加2的n次方;
利用而二進位制數來列舉每一種情況 00000 00000 00000 ~11111 11111 11111 (1<<15)
#include <iostream> #include <cstring> using namespace std; int arr[16][16],brr[16][16]; const int inf=1e9+7; int n; int change(int s) { memset(brr,0,sizeof(brr)); //不要忘了更新陣列 for(int i=0; i<n; i++) { if(s&(1<<i)) brr[0][i]=1; //給第一行brr賦值,實際上是brr[][]的01順序是的S的01 //相反的 else if(arr[0][i]==1) return inf; //1不能變成0 } for(int i=1;i<n;i++) for(int j=0;j<n;j++) { int sum=0; if(i>1) sum+=brr[i-2][j]; if(j>0) sum+=brr[i-1][j-1]; if(j<n) sum+=brr[i-1][j+1]; brr[i][j]=sum%2; //確定下一位是0 還是1 if(brr[i][j]==0&&arr[i][j]==1) return inf; } int cnt=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(brr[i][j]!=arr[i][j]) cnt++; } return cnt; } int main() { int T; cin >>T; for(int t=1; t<=T; t++) { cin >>n; for(int i=0; i<n; i++) for(int j=0; j<n; j++) cin >>arr[i][j]; int ans=inf; for(int i=0; i<(1<<n); i++) { int k=change(i); if(ans>k) ans=k; } if(ans!=inf) cout <<"Case "<<t<<": "<<ans<<endl; else cout <<"Case "<<t<<": "<<-1<<endl; } return 0; }