您的位置:首页 > 其它

uva11464(二进制枚举)

2017-10-13 20:35 253 查看

Even Parity

题意:给你n*n的矩阵,上面的元素不是0就是1,现在要求你把一些0变成1,使得矩阵中每一个元素上下左右和(存在的话)加起来为偶数,求最少的操作数。

思路:如果简单的暴力枚举的话会超时。我们可以枚举矩阵第一行的变化情况,然后往下推出下一行的变化情况(枚举每一个已知行的元素,如果当前元素不符合要求,查看该点下方是否可以从0变为1,不可以则这种方案不行,因为只有该点下方的那点在已知行外),

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#include <functional>
#define inf 1000000
using namespace std;
typedef long long ll;
const int MAXN=1e5+10;
const int MAX=100+10;
const double eps=1e-6;

int n;
int mapp[MAX][MAX];
int vis[MAX],t[MAX][MAX];
int d[6][3]={{-1,0},{1,0},{0,-1},{0,1}};

int solve(){
int ans=0;
for(int i=0;i<n;i++){
t[0][i]=vis[i];
if(mapp[0][i]==1&&vis[i]==0)
return -1;
if(mapp[0][i]==0&&vis[i]==1)
ans++;
}
for(int i=1;i<n;i++){
for(int j=0;j<n;j++){
t[i][j]=mapp[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int sum=0;
for(int k=0;k<=3;k++){
int xt=i+d[k][0];
int yt=j+d[k][1];
if(xt>=0&&xt<n&&yt>=0&&yt<n)
sum+=t[xt][yt];
}
if(sum%2==1){
if(i==n-1)
return -1;
if(i+1<n&&t[i+1][j]==0){
ans++;
t[i+1][j]=1;
}
else if(i+1<n&&t[i+1][j]==1){
//cout<<"*"<<endl;
return -1;
}
}
}
}
return ans;
}

int main(){
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif

int T,flag=1;
cin>>T;
while(T--){
cin>>n;
printf("Case %d: ",flag++);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>mapp[i][j];
}
}
int ans=inf;
for(int i=0;i<(1<<n);i++){
memset(vis,0,sizeof(vis));
for(int j=0;j<n;j++){
if(i&(1<<j)){
vis[j]=1;
}
}
int temp=solve();
if(temp!=-1&&temp<ans){
ans=temp;
}

4000
}
if(ans==inf)
cout<<-1<<endl;
else
cout<<ans<<endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva