POJ 3279 + UVA 11464 (二维翻转水题)

来源:互联网 发布:sql 注入漏洞 关键字 编辑:程序博客网 时间:2024/06/02 07:17

http://poj.org/problem?id=3279

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2459

两题都是翻转一个数,然后它的上下左右都跟着变化。

这种题目的做法是用DFS枚举出第一行的所有状态,当第一行的状态确定之后,那么下面的状态也唯一了。因为下一行总是依赖上一行。然后对于每种状态check后求值就可了。

POJ代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20;const int INF = 0x3f3f3f3f;int ismap[N][N];int ans[N][N],n,m,now,res=INF;int cnt[N][N];int pre[N][N];int change[N];bool check(int k){    if(k==n+1)     {        for(int i=1;i<=m;i++)        {            if(pre[k-1][i]) return false;         }        return true;    }    for(int i=1;i<=m;i++)    {       if(pre[k-1][i])        {           cnt[k][i]++;           now++;           pre[k-1][i] = 0;           pre[k][i] = pre[k][i] ? 0 : 1 ;           if(i>1) pre[k][i-1] = pre[k][i-1] ? 0: 1;           if(i<m) pre[k][i+1] = pre[k][i+1] ? 0 : 1;           if(k+1<=n) pre[k+1][i] = pre[k+1][i] ? 0 : 1;       }    }     check(k+1);}void dfs(int num){    if(num==m+1)     {        for(int i=1;i<=m;i++)        {            if(!change[i]) continue;            now ++;            cnt[1][i] ++;            pre[1][i] = pre[1][i] ? 0 : 1;            if(n>=2) pre[2][i] = pre[2][i] ? 0: 1;            if(i>1) pre[1][i-1] = pre[1][i-1] ? 0 : 1;            if(i<m) pre[1][i+1] =  pre[1][i+1] ? 0: 1;        }        if(check(2) && now < res)         {            memcpy(ans,cnt,sizeof(ans));            res = now;        }        now = 0;        memset(cnt,0,sizeof(cnt));        memcpy(pre,ismap,sizeof(pre));        return;    }    for(int ch = 0; ch<2 ; ch++)    {        if(!ch) dfs(num+1);        else        {            change[num] = 1;            dfs(num+1);            change[num] = 0;        }    }    return;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&ismap[i][j]),pre[i][j] = ismap[i][j];        now = 0;        res = INF;        memset(cnt,0,sizeof(cnt));        memset(change,false,sizeof(change));        dfs(1);        if(res==INF) printf("IMPOSSIBLE\n");        else            for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d%c",ans[i][j],j==m?'\n':' ');    }    return 0;}

UVA代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20;const int INF = 0x3f3f3f3f;int party[N][N];int num[N][N],n;int tmp[N][N],now,ans;bool change[N];int sum(int i,int j){    int sum = 0;    if(i-1>=1) sum+=num[i-1][j];    if(i+1<=n) sum+=num[i+1][j];    if(j-1>=1) sum+=num[i][j-1];    if(j+1<=n) sum+=num[i][j+1];    return sum;}void update(int i,int j){    if(i-1>=1)  tmp[i-1][j]++;    if(i+1<=n)  tmp[i+1][j]++;    if(j-1>=1)  tmp[i][j-1]++;    if(j+1<=n)  tmp[i][j+1]++;    return;}bool check(int k){    if(k==n+1)    {        for(int i=1;i<=n;i++)            if(tmp[n][i]%2) return false;        return true;    }    for(int i=1;i<=n;i++)    {        if(tmp[k-1][i]%2)        {            if(num[k][i]) return false;            now ++;            update(k,i);        }    }    check(k+1);}void dfs(int x){    if(x==n+1)    {        for(int i=1;i<=n;i++)        {            if(!change[i]) continue;             now++;            update(1,i);        }        if(check(2)) ans = min(ans,now);        memcpy(tmp,party,sizeof(tmp));        now = 0;         return;    }    if(num[1][x]) dfs(x+1);    else    {        for(int ch = 0; ch<2; ch++)        {           if(!ch) dfs(x+1);           else{              change[x] = true;              dfs(x+1);              change[x] = false;           }        }    }    return;}int main(){    int T;    scanf("%d",&T);    for(int cas = 1;cas<=T;cas++)    {       scanf("%d",&n);       for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)  scanf("%d",&num[i][j]);       for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)  party[i][j] = sum(i,j);       memset(change,false,sizeof(change));       memcpy(tmp,party,sizeof(tmp));       now = 0;       ans = INF;       dfs(1);       if(ans ==INF) ans = -1;       printf("Case %d: %d\n",cas,ans);    }    return 0;}
0 0
原创粉丝点击