UVA 11464 Even Parity
大意:给出一个n*n的 0、1矩阵(元素要么0要么1),把尽量少的0改成1,(1不能改成0)使得每个元素的上下左右的元素(如果存在的话)之和都为偶数。
如果枚举全部的话,那么效率会非常低。
而仅仅枚举第一行的话,那么数量相对而言就小了。
通过第一行推测出第二行,第二行在推测出第三行,最后与原矩阵比较。即可。
我用到了c++ STL里面的next_permutation求下一个排列 ^ ^
不过判断途中不符合条件直接用goto跳出交上去会报Compilation error。。。
T T什么时候得去下个G++。VS都能过哇。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; const int MAXN=20; const int INF=100000; int a[MAXN][MAXN],b[MAXN][MAXN],n,ans; void check(int num) { memset(b,0,sizeof(b)); if(num) for(int i=n-1;i>=num-1;i--) b[0][i]=1; do { bool ok=true; for(int i=0;i<n-1;i++) { for(int j=0;j<n;j++) { int sum=0; if(i>0) sum+=b[i-1][j];//up if(j>0) sum+=b[i][j-1];//left if(j<n-1) sum+=b[i][j+1];//right b[i+1][j]=sum%2; if(a[i+1][j]==1&&b[i+1][j]==0) {ok=false;break;} //改成goto 交上去报错。。 } if(!ok) break; } int count=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(a[i][j]!=b[i][j]) { if(a[i][j]==1&&b[i][j]==0) {ok=false;break;} count++; } } if(!ok)break; } if(ok) ans=min(ans,count); } while(next_permutation(b[0],b[0]+n)); } int main() { int repeat,ri; scanf("%d",&repeat); for(ri=1;ri<=repeat;ri++) { ans=INF; scanf("%d",&n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j]; for(int i=0;i<=n;i++) check(i); printf("Case %d: %d\n",ri,ans!=INF?ans:-1); } }
新 blog : www.hrwhisper.me