Fliptile【构造+贪心枚举】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/85234911

题目链接


  我们枚举第一列的答案,然后我们以此为基础向下搜索,题目要我们找的是‘1’数最少并且在‘1’数相等的时候,字典序最小的答案,直接按顺序枚举即可。

  给几组测试样例,过了这几组,就是基本过了,一道构造题,卡了为好几个小时……


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define son1 (j-1)>0? ans[i-1][j-1] : 0
#define son2 (j+1)<=M? ans[i-1][j+1] : 0
#define son3 (i-2)>0? ans[i-2][j] : 0
#define copppy(pr, ans) memcpy(pr, ans, sizeof(ans))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 18;
int N, M, mp[maxN][maxN], ans[maxN][maxN], cnt, pr[maxN][maxN], now;
bool check()
{
    now = 0;
    for(int i=1; i<=M; i++) if(ans[1][i]) now++;
    for(int i=2; i<=N; i++)
    {
        for(int j=1; j<=M; j++)
        {
            int s1 = son1, s2 = son2, s3 = son3;
            int tmp = mp[i-1][j] + s1 + ans[i-1][j] + s2 + s3;
            if( tmp & 1 ) { ans[i][j] = 1; now++; }
            else ans[i][j] = 0;
        }
    }
    for(int i=1; i<=M; i++) if( (ans[N-1][i] + mp[N][i] + ans[N][i-1] + ans[N][i+1] + ans[N][i]) & 1) return false;
    return true;
}
bool dfs_first_line(int y, int val)
{
    ans[1][y] = val;
    if(y == M)
    {
        bool flag = check();
        if(flag && cnt>now)
        {
            cnt = now;
            copppy(pr, ans);
        }
        return flag;
    }
    bool flag = dfs_first_line(y+1, 0);
    if(!flag) flag = dfs_first_line(y+1, 1);
    else dfs_first_line(y+1, 1);
    return flag;
}
int main()
{
    while(scanf("%d%d", &N, &M)!=EOF)
    {
        memset(ans, 0, sizeof(ans));
        memset(pr, 0, sizeof(pr));
        for(int i=1; i<=N; i++) for(int j=1; j<=M; j++) scanf("%d", &mp[i][j]);
        bool flag = false;
        cnt = INF;
        flag = dfs_first_line(1, 0);
        if(!flag) flag = dfs_first_line(1, 1);
        else dfs_first_line(1, 1);
        if(flag)
        {
            for(int i=1; i<=N; i++)
            {
                for(int j=1; j<=M; j++)
                {
                    printf("%d%c", pr[i][j], j==M?'\n':' ');
                }
            }
        }
        else printf("IMPOSSIBLE\n");
    }
    return 0;
}
/*
2 3
1 1 0
1 0 0
 ans:
1 0 0
0 0 0
/////
2 2
1 1
1 1
 ans:
1 1
1 1
/////
5 3
1 1 0
1 0 1
1 0 0
0 1 1
1 1 1
 ans:
0 0 0
1 1 0
1 0 0
1 0 0
0 0 1
 mine:
1 0 0
0 0 0
0 0 1
1 1 1
0 0 0
*/

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/85234911
今日推荐