题目链接:11464 - Even Parity
题意:
给你一个0、1矩阵,让你将其中的一些0变成1,使得每个位置的周围都是偶数个1.求最少将几个0变成1.
思路:
分析得出上两行确定之后,下一行为0或者1是确定的,要确定一个点为x,则看其上面的点周围的三个方向已经有y个1,则x+y=偶数,那么就能得出x为0或者1了。枚举第一行的状态之后依次递推下一行即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define maxn 1005 #define MAXN 50005 #define mod 1000000009 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 typedef long long ll; using namespace std; int n,m,ans,cnt,tot,flag; int mp[20],s[20]; void solve() { int i,j,t,num,col,row,x,y; ans=INF; tot=(1<<n)-1; for(i=0;i<=tot;i++) { if(!((i&mp[0])==mp[0])) continue ; flag=1; // printf("--------i:%d\n",i); memset(s,0,sizeof(s)); s[0]=i; num=0; for(j=0;j<n;j++) { if(!(mp[0]&(1<<j))&&(i&(1<<j))) num++; } for(row=1;row<n&&flag;row++) { for(col=0;col<n&&flag;col++) { x=0; if(col!=0) { if(s[row-1]&(1<<col-1)) x++; } if(col!=n-1) { if(s[row-1]&(1<<col+1)) x++; } if(row-2>=0) { if(s[row-2]&(1<<col)) x++; } if(x&1) // 1 { s[row]|=(1<<col); if(mp[row]&(1<<col)) ; else { num++; } } else // 0 { if(mp[row]&(1<<col)) flag=0; } } } if(flag) ans=min(ans,num); } } int main() { int i,j,t,test=0; scanf("%d",&t); while(t--) { scanf("%d",&n); int x; memset(mp,0,sizeof(mp)); for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&x); if(x) mp[i]|=(1<<j); } } solve(); if(ans==INF) ans=-1; printf("Case %d: %d\n",++test,ans); } return 0; }