bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏dfs

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏dfs相关的知识,希望对你有一定的参考价值。

这个可以用异或高斯消元,但是我不会呀我用的暴搜
2的m次方枚举第一行的翻转情况,然后后面的就定了,因为对于一个j位置,如果i-1的j位置需要翻,那么一定要翻i的j,因为这是i-1的j最后翻的机会
按字典序搜索然后取次数min即可

#include<cmath>  
#include<cstdio>  
#include<cstring>  
#include<iostream>  
#include<algorithm>  
using namespace std;  
const int N=20,inf=1707185547;  
int n,m,f[N][N],ans[N][N],p[N][N],a[N][N],mn=inf;  
void dfs(int x)  
{  
    if(x>m)  
    {  
        for(int i=1;i<=n;i++)  
            for(int j=1;j<=m;j++)  
                p[i][j]=a[i][j];  
        for(int i=1;i<=m;i++)  
            if(f[1][i])  
            {  
                p[1][i]^=1,p[2][i]^=1;  
                p[1][i+1]^=1,p[1][i-1]^=1;  
            }  
        for(int i=2;i<=n;i++)  
            for(int j=1;j<=m;j++)  
                {  
                    if(p[i-1][j]==1)  
                    {  
                        f[i][j]=1;  
                        p[i][j]^=1;  
                        p[i][j+1]^=1,p[i][j-1]^=1;  
                        p[i+1][j]^=1,p[i-1][j]^=1;  
                    }  
                    else 
                        f[i][j]=0;  
                    if(p[i-1][j]) 
                        return;  
                }  
        bool flag=false;  
        for(int i=1;i<=n;i++)  
            for(int j=1;j<=m;j++)  
                if(p[i][j])  
                {  
                    flag=true;  
                    break;  
                }  
        if(!flag)  
        {  
            int tot=0;  
            for(int i=1;i<=n;i++)  
                for(int j=1;j<=m;j++)  
                    if(f[i][j]) 
                        tot++;  
            if(tot>=mn) 
                return;  
            mn=tot;  
            for(int i=1;i<=n;i++)  
                for(int j=1;j<=m;j++)  
                    ans[i][j]=f[i][j];  
        }  
        return;  
    }  
    for(int i=0;i<=1;i++)  
    {  
        f[1][x]=i;  
        dfs(x+1);  
    }  
}  
int main()  
{  
    scanf("%d%d",&n,&m);  
    for(int i=1;i<=n;i++)  
        for(int j=1;j<=m;j++)  
            scanf("%d",&a[i][j]);  
    dfs(1);  
    if(mn==inf) 
        printf("IMPOSSIBLE");  
    else  
    {  
        for(int i=1;i<=n;i++)  
        {  
            for(int j=1;j<m;j++)  
            printf("%d ",ans[i][j]);  
            printf("%d\n",ans[i][m]);  
        }  
    }  
    return 0;
}  

以上是关于bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏dfs的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏dfs

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&&bzoj1692[Usaco2007 Dec]队列变换*

bzoj2023[Usaco2005 Nov]Ant Counting 数蚂蚁*&&bzoj1630[Usaco2007 Demo]Ant Counting*

bzoj1710Usaco2007 OpenCheappal 便宜回文

[BZOJ] 1636: [Usaco2007 Jan]Balanced Lineup

bzoj 1692: [Usaco2007 Dec]队列变换