码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-05-26 23:26:33      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:pos   scan   flip   amp   false   pac   scanf   clu   mes   

这个可以用异或高斯消元,但是我不会呀我用的暴搜
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】

标签:pos   scan   flip   amp   false   pac   scanf   clu   mes   

原文地址:https://www.cnblogs.com/lokiii/p/9094576.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!