zoukankan      html  css  js  c++  java
  • POJ 3279 Fliptile

    Description

    Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

    As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

    Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

    Input

    Line 1: Two space-separated integers: M and N 
    Lines 2..M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

    Output

    Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

    Sample Input

    4 4
    1 0 0 1
    0 1 1 0
    1 0 0 1
    0 1 1 0

    Sample Output

    0 0 0 0
    1 0 0 1
    0 0 0 0
    1 0 0 1

    这个是一个反转的问题,参考上一次学习的反转问题http://blog.csdn.net/chilumanxi/article/details/46367927
    那个问题可以从左向右依次确定状态,最先确定的是第一个元素的状态。第一个元素的状态确定后,后面的元素状态随之确定。但是这个题面临的问题是即使是从上向下反转,那么每个点也会有多种反转方式,所以我们需要像那个题一样,确定第一排的状态,然后依次向后推,这样从第二排开始改状态,就可以有针对性了。
    用二进制枚举第一行的状态。然后搜索后面的情况。第一行共有2的N次幂个状态,对每个状态进行枚举
    创建三个数组,用来存储输入的数组,操作的数组和输出的数组,一些在处理的时候边界的细节问题见代码
    代码如下:
    /*************************************************************************
    	> File Name: Fliptile.cpp
    	> Author: Zhanghaoran0
    	> Mail: chiluamnxi@gmail.com
    	> Created Time: 2015年07月25日 星期六 15时10分09秒
     ************************************************************************/
    
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #define maxn 20
    
    using namespace std;
    
    int N, M;
    int a[maxn][maxn], b[maxn][maxn];
    int output[maxn][maxn]; 
    bool flag = false;
    
    bool check(int x){
        for(int i = 0; i < N; i ++){
            if(x & (1 << i)){
                output[0][i] = 1;
                b[0][i] ^= 1;
                if(M > 1)
                    b[1][i] ^= 1;
                if(i - 1 >= 0)
                    b[0][i - 1] ^= 1;
                if(i + 1 < N)
                    b[0][i + 1] ^= 1;
            }
        }
    
        for(int i = 1; i < M; i ++){
            for(int j = 0; j < N; j ++){
                if(b[i - 1][j]){
                    output[i][j] = 1;
                    b[i][j] ^= 1;
                    b[i - 1][j] ^= 1;
                    if(i + 1 < M)
                        b[i + 1][j] ^= 1;
                   if(j - 1 >= 0)
                        b[i][j - 1] ^= 1;
                    if(j + 1 < N)
                       b[i][j + 1] ^= 1;
                    }
                }
            }
    
            for(int i = 0; i < N; i ++){
                if(b[M - 1][i])
                    return false;
            }
        return true;
    }
    
    
    int main(void){
        while(scanf("%d%d", &M, &N) != EOF){
            for(int i = 0; i < M; i ++){
                for(int j = 0; j < N; j ++){
                    cin >> a[i][j];
                }
            }
            flag = false;
            for(int i = 0; i < (1 << N); i ++){
                memcpy(b, a, sizeof(a));
                memset(output, 0, sizeof(output));
                if(check(i)){
                    flag = true;
                    for(int k = 0; k < M; k ++){
                        for(int j = 0; j < N; j ++){
                            cout << output[k][j] << " ";
                        }
                        cout << endl;
                    }
                    break;
                }
            }
            if(!flag)
                cout << "IMPOSSIBLE" << endl;
        }
        return 0;
    }


  • 相关阅读:
    服务器性能测试实时监控Linux命令
    软件性能测试中的关键指标
    递归静态路由和直连静态路由
    FIB表与RIB表的区别与联系
    FIB表中 Next Hop 的几种状态码(drop/receive/attached/no route)的含义
    Leetcode 与树(TreeNode )相关的题解测试工具函数总结
    centos 7.6 docker 安装 nextcloud -使用sqlite数据库
    看守所收押流程
    qt编译oracle驱动,qt 5.12 连接 oracle 数据库示例代码
    centos 7.6 安装配置nginx (显示中文目录,带密码验证)
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136103.html
Copyright © 2011-2022 走看看