zoukankan      html  css  js  c++  java
  • P1985 [USACO07OPEN]翻转棋 Fliptile S

    95. 费解的开关同题。

    暴力总共有(2^{NM})种翻转的方法。

    先确定第一行的翻转方式,然后可以很容易判断这样是否存在解以及解的最小步数是多少,最上面一行的翻转方式共有(O(2^M))种,复杂度为(O(NM2^M))

    const int N=20;
    bool g[N][N],tmp[N][N];
    int flip[N][N],ans[N][N];
    int n,m;

    bool check(int x,int y)
    {
    return x>=0 && x<n && y>=0 && y<m;
    }

    void change(int x,int y)
    {
    flip[x][y]=1;
    for(int i=0;i<5;i++)
    {
    int a=x+dx[i],b=y+dy[i];
    if(check(a,b))
    tmp[a][b]^=1;
    }
    }

    int main()
    {
    cin>>n>>m;

    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>g[i][j];
    
    int res=INF;
    for(int s=0;s<(1<<m);s++)
    {
        memcpy(tmp,g,sizeof g);
        memset(flip,0,sizeof flip);
    
        int cnt=0;
        for(int i=0;i<m;i++)
            if(s>>i & 1)
                change(0,i),cnt++;
    
        for(int i=0;i<n-1;i++)
            for(int j=0;j<m;j++)
                if(tmp[i][j])
                    change(i+1,j),cnt++;
    
        bool ok=true;
        for(int i=0;i<m;i++)
            if(tmp[n-1][i])
            {
                ok=false;
                break;
            }
    
        if(ok && cnt < res)
        {
            res=cnt;
            memcpy(ans,flip,sizeof flip);
        }
    }
    
    if(res == INF) puts("IMPOSSIBLE");
    else
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                cout<<ans[i][j]<<' ';
            cout<<endl;
        }
    }
    //system("pause");
    return 0;
    

    }

  • 相关阅读:
    SpringBoot 拦截器
    SpringBoot学习笔记1
    mysql学习1
    mybatis运行原理学习
    js学习2
    设计原则
    mybatis学习1
    spring mvc
    Jenkins流水线部署maven不同模块服务到不同服务器运行
    L2Dwidget让自己的vue项目骚起来
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14560121.html
Copyright © 2011-2022 走看看