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

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 
#include 
#include 
#include 
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(i1] = 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(i1][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 
#include 
#include 
#include 
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;
}

你可能感兴趣的:(*Search,Agorithm,*Others)