POJ3279 Fliptile

题目:

给你一个01矩阵,矩阵大小为M x N。(1 <= M , N <= 15)
每次操作选择一个格子,使得该格子与上下左右四个格子的值翻转。
至少多少次操作可以使得矩阵中所有的值变为0?
请输出翻转方案,若没有方案,输出"IMPOSSIBLE” 。
若有多种方案符合题意,请首先输出翻转次数最少的方案;若方案个数仍不唯一,则输出字典序最小的方案。

输入:

第一行输入两个数:M和N。(1 <= M , N <= 15)
接下来M行,每行N个数,其值只为0或1。

输出:

输出M行,每行N个数。
每个数代表该位置翻转次数

样例:

分析:状态压缩(´A`。) wa得我不省人事

 

#include<iostream>
#include<sstream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<numeric>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<cctype>
#define PI acos(-1.0)
const int INF = 0x3f3f3f;
const int NINF = -INF - 1;
typedef long long ll;
using namespace std;
int m, n;
int dx[5] = {0, 1, 0, -1, 0}, dy[5] = {0, 0, 1, 0, -1};
int arr[20][20], temp[20][20], ans[20][20];
int judge(int x, int y)
{
    int sum = arr[x][y];
    for (int i = 0; i < 5; ++i)
    {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx >= 0 && nx < m && ny >= 0 && ny < n)
            sum += temp[nx][ny];
    }
    return sum % 2;
}
int cal()
{
    for (int i = 1; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (judge(i - 1, j) == 1)
                temp[i][j] = 1;
        }
    }
    for (int j = 0; j < n; ++j)
    {
        if (judge(m - 1, j) == 1) return -1;
    }
    int num = 0;
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
            num += temp[i][j];
    }
    return num;
}
void func()
{
    int flag = -1;
    for (int i = 0; i < 1 << n; ++i)
    {
        memset(temp, 0, sizeof(temp));
        for (int j = 0; j < n; ++j)
        {
            temp[0][n - j - 1] = i >> j & 1;
        }
        int num = cal();
        if (num >= 0 && (flag < 0 || num < flag))
        {
            flag = num;
            memcpy(ans, temp, sizeof(temp));
        }
    }
    if (flag < 0) cout << "IMPOSSIBLE" << endl;
    else
    {
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                cout << ans[i][j];
                if (j != n - 1) cout << ' ';
            }
            cout << endl;
        }
    }
}
int main()
{
    cin >> m >> n;
    for (int i = 0; i < m; ++i)
    {
        for (int j = 0; j < n; ++j)
            cin >> arr[i][j];
    }
    func();
    return 0;
}

 

posted @ 2019-06-04 00:15  Veasky  阅读(391)  评论(0编辑  收藏  举报