ACM篇:POJ 3279 -- Fliptile

網上題解很多了。

枚舉第一行情況,然後遍歷2至n行:若上一個元爲“1”,則翻轉當前元(因爲只有這樣才能改變上一元)。
最後檢驗最後一行是否全零。

#include <iostream>
#include <cstdio>
#include <cstring>

const int MAX = 15;

using namespace std;

int n;
int m;
int ans;
int step;
bool loc[MAX+2][MAX+2];
bool temp_loc[MAX+2][MAX+2];
bool tile[MAX+2][MAX+2];
bool temp_tile[MAX+2][MAX+2];

void read_tile()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", &tile[i][j]);
}

const int ROW[] = {0, 0, 0, 1, -1};
const int COL[] = {0, 1, -1, 0, 0};
void _flip(int r, int c)
{
    for (int i = 0; i < 5; i++)
        temp_tile[r+ROW[i]][c+COL[i]] = !temp_tile[r+ROW[i]][c+COL[i]];
}

void _enumberate(int ord)
{
    for (int j = 1; j <= m; j++)
    {
        if (ord & 1) 
        {
            _flip(1, j);
            temp_loc[1][j] = true;
            step++;
        }
        ord >>= 1;
    }
}

void _operate()
{
    for (int i = 2; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (temp_tile[i-1][j])
            {
                _flip(i, j);
                temp_loc[i][j] = true;
                step++;
            }
        }
    }
}

bool is_ok()
{
    for (int j = 1; j <= m; j++)
        if (temp_tile[n][j])
            return false;
    return true;
}

bool lesser(bool temp_loc[][MAX+2], bool loc[][MAX+2])
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            if (temp_loc[i][j] == loc[i][j])
                continue;
            return (temp_loc[i][j] < loc[i][j]);
        }
    return false;
}   

void _print(bool mark)
{   
    if (mark)
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
                printf("%d ", loc[i][j]);
            putchar('\n');
        }
    }
    else 
        printf("IMPOSSIBLE");
}
int main()
{
    //  input
    read_tile();

    //  work
    int sz;
    bool mark = false;

    sz = 1 << m;
    ans = MAX * MAX;

    for (int i = 0; i < sz; i++)
    {
        step = 0;
        memset(temp_loc, 0, sizeof(temp_loc));
        memcpy(temp_tile, tile, sizeof(tile));

        _enumberate(i);
        _operate();
        if(is_ok())
        {
            mark = true;
            if (step < ans)
            {
                ans = step;
                memcpy(loc, temp_loc, sizeof(temp_loc));
            }
            else if (step == ans && lesser(temp_loc, loc))
            {
                memcpy(loc, temp_loc, sizeof(temp_loc));
            }
        }
    }
    _print(mark);

    return 0;
}
發佈了58 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章