HDU-5113 Black And White (剪枝)

http://acm.hdu.edu.cn/showproblem.php?pid=5113

题意:

四色问题,一个nxm的矩阵,K种颜色分别给出他们的个数,相邻的小方块不能同色,问能不能染成四色问题

思路:

一个DFS对这个矩阵的每一层进行爆搜,对于颜色数量大于矩阵数量一半的直接进行剪枝

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <string.h>
#include <queue>
#include <stack>
#include <deque>
#include <stdlib.h>
#include <bitset>

using namespace std;

#define ll long long
#define ull unsigned long long
const int INF = 0x3f3f3f3f;
const int maxn = 6;
const int eps = 1e-8;
const int M = 1e9 + 7;

struct COL{
    int val, id;
}color[30];

bool cmp(COL a, COL b) {
    return a.val > b.val;
}

bool ccmp(int a, int b) {
    return a > b;
}

int n, m, k;
int mp[maxn][maxn];
bool vis = 0;
int tmp[30];

void dfs(int x, int y) {
    if (y > m) {
        x ++;y = 1;
    }
    if (x > n) {
        vis = 1;
        return ;
    }
    for (int i = 1; i <= k; i ++) {
        int id = color[i].id;
        if(!color[i].val) continue;
        if(y > 1 && mp[x][y - 1] == id) continue; //上面有这种颜色,剪掉
        if(x > 1 && mp[x - 1][y] == id) continue; // 左边有这种颜色,剪掉
        for (int j = 1; j <= k; j ++)
            tmp[j] = color[j].val;
        sort(tmp + 1, tmp + 1 + k, ccmp);
        if(tmp[2] == 0 && tmp[1] > 1) continue;//出现了只剩一种颜料的情况
        if(tmp[3] == 0 && tmp[2] && tmp[1] > 2 * tmp[2]) continue;//出现只剩两种颜料,但第一大的颜料比第二大的颜料2倍要大
        color[i].val --;
        mp[x][y] = id;
        dfs(x, y + 1);
        if(vis) return;
        color[i].val ++;
    }
}


int main(int argc, const char * argv[]) {
    int T;
    scanf("%d", &T);
    int karse = 0;
    while(T --) {
        memset(color, 0, sizeof(color));
        memset(mp, 0, sizeof(mp));
        scanf("%d %d %d", &n, &m, &k);
        for (int i = 1; i <= k; i ++) {
            scanf("%d", &color[i].val);
            color[i].id = i;
        }
        vis = 0;
        sort(color + 1, color + k + 1, cmp);
        printf("Case #%d:\n", ++karse);
        if(color[1].val > (n * m + 1)/2) { //如果第一大的颜色数量大于总矩阵的一半,直接NO
            printf("NO\n");
            continue;
        }
        dfs(1, 1);
        if(!vis)
            printf("NO\n");
        else {
            printf("YES\n");
            for (int i = 1; i <= n; i ++) {
                for (int j = 1; j <= m; j ++){
                    if(j == 1) printf("%d", mp[i][j]);
                    else printf(" %d", mp[i][j]);
                }
                printf("\n");
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81661720