Poj 3279Fliptile (enumeración binaria)

Portal de temas

Significado de la pregunta: Dada una matriz de 0, 1 e invirtiendo una posición cada vez, sus cuatro posiciones adyacentes también se invertirán (si existe). La inversión significa 1-> 0 o 1-> 0. Pregunta Invierta el número mínimo de posiciones para hacer que la matriz sea todo 0. Finalmente, genere una matriz y genere 1 para todas las posiciones invertidas; de lo contrario, genere 0. Si hay varias respuestas con la misma respuesta, genere la matriz con el orden lexicográfico más pequeño.

Comience a invertir desde la primera línea, use binario para enumerar, enumere todas las opciones posibles de la primera línea, cuando la primera línea se invierte, se determina cada línea subsiguiente y la segunda línea comienza una por una El elemento se juzga. Si el elemento anterior en la misma columna del elemento es 1, entonces el elemento actual se invierte. Después de la enumeración final, solo la última fila puede tener 1. Sólo juzgue.

El proceso de enumeración binaria asegura que el orden lexicográfico sea pequeño primero.

código:

#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;
}

 

Supongo que te gusta

Origin blog.csdn.net/qq_44115065/article/details/106148510
Recomendado
Clasificación