题目链接: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;
}