Uva-11464-Even Parity

来源:互联网 发布:50本网络禁书txt下载 编辑:程序博客网 时间:2024/05/08 14:40

这个问将所给m*n的01矩阵,需要求出最少将0变成1的次数,使得所有点的上下左右之和为偶数。有题目的要求可以知道如果对整个地图用DFS的话会超时,而且超时会很严重,而通过观察可以发现后面的几行可以由第一行递推得出。

解法:

首先用DFS枚举第一行的所有情况,然后对每种情况进行递推后面的变化情况,然后取最小即可。

代码:

#include<cstdio>#include<cstring>#include<iostream>#define MAX 16using namespace std;const int maxn=1<<16,inf=1<<28;int n,map[MAX][MAX],vis[maxn],step,ans;int movex[3]={0,-1,0},movey[4]={1,0,-1};bool isborder(int x,int y){    if(x<0||x>=n||y<0||y>=n)return true;    return false;}void Deal(){    int anst=step;    int imap[MAX][MAX];    memcpy(imap,map,sizeof(map));    for(int i=0;i<n-1;i++)for(int j=0;j<n;j++){    int sum=0;    for(int k=0;k<3;k++)    {int itx=i+movex[k];int ity=j+movey[k];if(isborder(itx,ity))    continue;sum+=imap[itx][ity];    }    if(imap[i+1][j])    {sum++;if(sum&1)    return;    }    else    {if(sum&1){    imap[i+1][j]=1;    anst++;}    }}    for(int j=0;j<n;j++)    {int sum=0;for(int k=0;k<3;k++){    int itx=n-1+movex[k];    int ity=j+movey[k];    if(isborder(itx,ity))continue;    sum+=imap[itx][ity];}if(sum&1)    return;    }    ans=min(ans,anst);}void DFS(int deep){    if(deep==n)    {Deal();return ;    }    if(!map[0][deep])    {map[0][deep]=1;step++;DFS(deep+1);step--;map[0][deep]=0;    }    DFS(deep+1);}int main(){    int T,cas=1;    scanf("%d",&T);    while(T--)    {scanf("%d",&n);for(int i=0;i<n;i++)    for(int j=0;j<n;j++)scanf("%d",&map[i][j]);step=0,ans=inf;DFS(0);if(ans==inf)    printf("Case %d: -1\n",cas++);else    printf("Case %d: %d\n",cas++,ans);    }    return 0;}


原创粉丝点击