2014ACM Regional北京现场赛B题——HDU5113

来源:互联网 发布:淘宝搜不到情趣用品 编辑:程序博客网 时间:2024/05/02 02:39

题目描述:

给出k种颜色,给n*m的格子染色,保证任意一个格子与周围格子颜色不同。

大致思路:

这个题可以搜索+剪枝过,但是更巧妙的方法就是构造法,构造的过程很简单,先将n*m的格子黑白染色,使得任意黑格子周围都是白格子,之后挑最大的颜色给黑格子染色,如果染完还剩的话就一定无解,如果染完,就挑数量最少的颜色继续染黑格子,之后将剩下的颜色任意放在白格子里就可以了。但是这样构造有一个小问题,就是在行过少的时候,比如5*2的格子,三种颜色,分别是3 3 4,这样按照这个过程就会出问题,所以就想到了保证不会出错的方法,就是当行小于列的时候,将行列交换,染完颜色之后转置输出。

代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <queue>#include <vector>#include <set>#include <map>#include <string>using namespace std;typedef long long ll;typedef vector<int> vint;#define RD(x) scanf("%d",&x)#define CLR(a,b) memset(a,b,sizeof(a))int n,m,k;int a[100];int mm[10][10];int main() {    //freopen("in.txt","r",stdin);    int T;    cin>>T;    for (int t = 1; t <= T; t++) {        CLR(mm,0);        cin>>n>>m>>k;        int tmpn = n,tmpm = m;        if (n < m) swap(n,m);        //cout<<n<<" "<<m<<" "<<k<<endl;        bool flag = false;        for (int i = 1; i <= k; i++) RD(a[i]);        if (n == 2 && m == 3 && k == 3 && a[1] == 2 && a[2] == 2) flag = true;        int tmp = 1;        for (int i = 1; i <= k; i++) {            if (a[i] > a[tmp]) tmp = i;        }        int sum = 0;        if (m % 2 && n % 2) {            sum = (m/2+1)*(n/2+1)+(m/2)*(n/2);        }        else if (m % 2) {            sum = (m/2+1+m/2)*(n/2);        }        else sum = (m/2)*n;        printf("Case #%d:\n",t);        if (a[tmp] > sum) {            printf("NO\n");            continue;        }        //cout<<sum<<" "<<tmp<<endl;        sum -= a[tmp];        for (int i = 1; i <= n; i++) {            if (i % 2 == 0) {                for (int j = 2; j <= m; j += 2) {                    mm[i][j] = tmp;                    a[tmp]--;                    //cout<<i<<" "<<j<<mm[2][1]<<endl;                    if (a[tmp] == 0) break;                }            }            else {                for (int j = 1; j <= m; j += 2) {                    mm[i][j] = tmp;                    a[tmp]--;                    //cout<<i<<" "<<j<<mm[2][1]<<endl;                    if (a[tmp] == 0) break;                }            }            if (a[tmp] == 0) break;        }        while (sum > 0) {            tmp = 1;            while (a[tmp] == 0) tmp++;            for (int i = tmp + 1; i <= k; i++) if (a[i] < a[tmp] && a[i]) tmp = i;            if (sum < a[tmp]) {                sum = 0;                for (int i = 1; i <= n; i++) {                    if (i % 2 == 0) {                        for (int j = 2; j <= m; j += 2) {                            if (mm[i][j] != 0) continue;                            mm[i][j] = tmp;                            a[tmp]--;                            if (a[tmp] == 0) break;                        }                    }                    else {                        for (int j = 1; j <= m; j += 2) {                            if (mm[i][j] != 0) continue;                            mm[i][j] = tmp;                            a[tmp]--;                            if (a[tmp] == 0) break;                        }                    }                    if (a[tmp] == 0) break;                }                for (int i = 1; i <= n; i++) {                    for (int j = 1; j <= m; j++) {                        if (mm[i][j] != 0) continue;                        mm[i][j] = tmp;                        a[tmp]--;                        if (a[tmp] == 0) break;                    }                    if (a[tmp] == 0) break;                }            }            else {                sum -= a[tmp];                for (int i = 1; i <= n; i++) {                    if (i % 2 == 0) {                        for (int j = 2; j <= m; j += 2) {                            if (mm[i][j] != 0) continue;                            mm[i][j] = tmp;                            a[tmp]--;                            if (a[tmp] == 0) break;                        }                    }                    else {                        for (int j = 1; j <= m; j += 2) {                            if (mm[i][j] != 0) continue;                            mm[i][j] = tmp;                            a[tmp]--;                            if (a[tmp] == 0) break;                        }                    }                    if (a[tmp] == 0) break;                }            }        }        tmp = 1;        while (a[tmp] == 0) tmp++;        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                if (mm[i][j] != 0) continue;                mm[i][j] = tmp;                a[tmp]--;                while (a[tmp] == 0) tmp++;            }        }        if (flag) {            mm[1][1] = mm[2][3] = 1;            mm[1][2] = mm[2][1] = 2;            mm[1][3] = mm[2][2] = 3;        }        /*flag = true;        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                if (mm[i][j] == mm[i-1][j] || mm[i][j] == mm[i+1][j] || mm[i][j] == mm[i][j-1] || mm[i][j] == mm[i][j+1]) flag = false;            }        }        if (flag == false) {            printf("NO\n");            continue;        }*/        printf("YES\n");        if (tmpn == n) {            for (int i = 1; i <= n; i++) {                for (int j = 1; j <= m; j++) {                    if (j != 1) printf(" %d",mm[i][j]);                    else printf("%d",mm[i][j]);                }                printf("\n");            }        }        else {            for (int i = 1; i <= m; i++) {                for (int j = 1; j <= n; j++) {                    if (j != 1) printf(" %d",mm[j][i]);                    else printf("%d",mm[j][i]);                }                printf("\n");            }        }    }}


3 0