• D


    题目大意
    翻瓷砖(姑且认为题目就是这个意思吧)
        农民约翰知道越聪明越快乐的牛产的牛奶越多(神马鬼理论),于是他开始安排牛进行一个智力运动在一个M*N (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的网格中,每个网格都有一个正方形的瓷砖组成,当然每块瓷砖都是由黑色和白色两种颜色组成的。
        这个游戏是吧所有的瓷砖都变成白色??,奶牛在翻转瓷砖的时候会把四周的瓷砖一同翻转过来的,当然奶牛想用最少的步骤来翻转,如果有多种翻转方法,输出字典序最小的那个(矩形的字典序。。。。),如果不能完成翻转,输出IMPOSSIBLE


    通过观察可以看出来一共有 2 ^(M*N)种翻转方式,当然不能一种一种的实验,那样会超时到死的,不过通过观察可以看出来只要第一行的翻转方案确认了,那么下面的也可以知道了,因为如果有一个瓷砖需要翻转,本行翻转方法已经确认,那么一定在同列的下行翻转。这样只需要2^15就够了。
    写一下试试吧........
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<queue>
    using namespace std;

    #define maxn 30
    const int oo = 0xffffff;

    //本身和四周的位置,因为需要保存翻转的方法,所以不改变上层
    int dir[4][2] = { {0,0},{0,1},{0,-1},{1,0} };
    int G[maxn][maxn], ans[maxn][maxn];
    int M, N;

    //初始化第0层并且复制图到ans
    void Start(int k)
    {
        int i, j;

        for(i=N; i>0; i--)
        {
            ans[0][i] = k%2;
            k /= 2;
        }

        for(i=1; i<=M; i++)
        for(j=1; j<=N; j++)
            ans[i][j] = G[i][j];
    }
    int  OK()//判断翻转后的图是否合法
    {
        int i;

        for(i=1; i<=N; i++)
            if(ans[M][i])return 0;

        return 1;
    }
    //翻转图,并且返回需要翻转的步数,若不能翻转成功则返回-1
    int  OverTurn()
    {
        int i, j, k, sum=0;

        for(i=1; i<=M; i++)
        for(j=1; j<=N; j++)
        {
            if(ans[i-1][j])
            {
                for(k=0; k<4; k++)
                {
                    sum++;
                    int ni = i+dir[k][0];
                    int nj = j+dir[k][1];

                    ans[ni][nj] = !ans[ni][nj];
                }
            }
        }

        if(OK() == 0)
            return -1;

        return sum;
    }

    int  main()
    {
        while(scanf("%d%d", &M, &N) != EOF)
        {
             int i, j, k=pow(2, N);
             int sum = oo, p, q=-1;//sum 需要翻转的步数

             for(i=1; i<=M; i++)
             for(j=1; j<=N; j++)
                scanf("%d", &G[i][j]);

             for(i=0; i<=k; i++)
             {
                 Start(i);
                 p = OverTurn();

                 if(p != -1 && sum > p)
                    sum = p, q = i;
             }

             if(q == -1)
                printf("IMPOSSIBLE ");
             else
             {
                 Start(q);
                 OverTurn();

                 for(i=0; i<M; i++)
                 for(j=1; j<=N; j++)
                    printf("%d%c", ans[i][j], j==N?' ':' ');
             }
        }

        return 0;

    } 

  • 相关阅读:
    Schema约束
    gitalk报错问题
    SQL语句中单引号、双引号和反引号的区分
    用Eclipse上传项目到github
    git服务器搭建
    使用IntelliJ IDEA和Eclipse导入Github项目
    事务隔离级别的简单理解
    大公司里怎样开发和部署前端代码?
    页面无刷新Upload File
    MVC 文件上传问题
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4648351.html
Copyright © 2020-2023  润新知