Poj 3279Fliptile (binary enumeration)

Topic portal

The meaning of the question: Given a matrix of 0, 1 and inverting one position each time, its four adjacent positions will also be inverted (if it exists). Inversion means 1->0 or 1->0. Question Reverse the minimum number of positions to make the matrix all 0. Finally, output a matrix, and output 1 for all inverted positions, otherwise output 0. If there are multiple answers with the same answer, output the matrix with the smallest lexicographic order.

Start inverting from the first line, use binary to enumerate, enumerate all the possible choices of the first line, when the first line is reversed, every subsequent line is determined, and the second line starts one by one The element is judged. If the previous element in the same column of the element is 1, then the current element is reversed. After the final enumeration, only the last row may have 1s. Just judge.

The process of binary enumeration ensures that the lexicographic order is small first.

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <sstream>
#include <cstring>
#include <set>
#include <cctype>
#include <bitset>
#define IO                       \
    ios::sync_with_stdio(false); \
    // cin.tie(0);                  \
    // cout.tie(0);
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
const int maxm = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 11092019;
int dis[8][2] = {0, 1, 1, 0, 0, -1, -1, 0, 1, -1, 1, 1, -1, 1, -1, -1};
int a[20][20];
int b[20][20];
int temp[20][20];
int ans[20][20];
int res = inf;
int n, m;
void filp(int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        int tx = x + dis[i][0];
        int ty = y + dis[i][1];
        b[tx][ty] = !b[tx][ty];
    }
}
int rep()
{
    int cnt = 0;
    for (int j = 0; j < m; j++)
        if (temp[0][j])
        {
            cnt++;
            b[0][j] = !b[0][j];
            filp(0, j);
        }
    for (int i = 1; i < n; i++)
        for (int j = 0; j < m; j++)
            if (b[i - 1][j])
            {
                cnt++;
                b[i][j] = !b[i][j];
                temp[i][j] = 1;
                filp(i, j);
            }
    for (int j = 0; j < m; j++)
        if (b[n - 1][j] == 1)
            return inf;
    return cnt;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    // IO;
    cin >> n >> m; // n 行 m 列
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> a[i][j];
    for (int s = 0; s < (1 << m); s++)
    {
        memset(temp, 0, sizeof temp);
        memcpy(b, a, sizeof a);
        for (int j = 0; j < m; j++)
            if (s & (1 << j))
                temp[0][j] = 1;
        int t = rep();
        if (t < res)
        {
            res = t;
            memcpy(ans, temp, sizeof temp);
        }
    }
    if (res == inf)
        cout << "IMPOSSIBLE";
    else
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m - 1; j++)
                printf("%d ", ans[i][j]);
            printf("%d\n", ans[i][m - 1]);
        }
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_44115065/article/details/106148510