hdu5113 贪心搜索 2014ACM/ICPC亚洲区北京站 B题 Black And White

题意:一个n*m的棋盘,最大是5*5的,最多25个格子,然后在格子上涂色,告诉你有a种颜色,每种颜色涂xi个格子,问有没有一种涂法,使得相邻的格子颜色都不一样,有临边才算相邻。

思路:一道考验智商的题目,首先想到的肯定是爆搜了,但是需要剪枝,但是不知道如何下手。首先可以确定的是,只要有一个x>(n*m+1)/2,直接就挂掉了,输出NO,然后想着想着就觉得这个东西应该能贪心解决。首先把不同颜色的多少排个序,把最多的那个颜色拿出来,斜着往格子里放,斜着空一行放一行,放完最多的一种颜色就放最少的颜色(其实放完最多的接着放最多的也无妨吧,为了保险,就先这样了。。。),然后依次放就好了。贪心的解决掉。注意这里有个小技巧,可以用一个截距b来控制一个斜行的参数,代码简单一些。

感想:这是一道北京区域赛的银牌题,现场只有39个AC的队伍,但是我跟队友在私下做,半个小时就A了,这说明题目真的不可怕,只要现场赛中沉着冷静,一定能拿出好名次的






Black And White

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 2344    Accepted Submission(s): 633
Special Judge


Problem Description
In mathematics, the four color theorem, or the four color map theorem, states that, given any separation of a plane into contiguous regions, producing a figure called a map, no more than four colors are required to color the regions of the map so that no two adjacent regions have the same color.
— Wikipedia, the free encyclopedia

In this problem, you have to solve the 4-color problem. Hey, I’m just joking.

You are asked to solve a similar problem:

Color an N × M chessboard with K colors numbered from 1 to K such that no two adjacent cells have the same color (two cells are adjacent if they share an edge). The i-th color should be used in exactly c i cells.

Matt hopes you can tell him a possible coloring.
 

Input
The first line contains only one integer T (1 ≤ T ≤ 5000), which indicates the number of test cases.

For each test case, the first line contains three integers: N, M, K (0 < N, M ≤ 5, 0 < K ≤ N × M ).

The second line contains K integers c i (c i > 0), denoting the number of cells where the i-th color should be used.

It’s guaranteed that c 1 + c 2 + · · · + c K = N × M .
 

Output
For each test case, the first line contains “Case #x:”, where x is the case number (starting from 1). 

In the second line, output “NO” if there is no coloring satisfying the requirements. Otherwise, output “YES” in one line. Each of the following N lines contains M numbers seperated by single whitespace, denoting the color of the cells.

If there are multiple solutions, output any of them.
 

Sample Input
   
   
   
   
4 1 5 2 4 1 3 3 4 1 2 2 4 2 3 3 2 2 2 3 2 3 2 2 2
 

Sample Output
   
   
   
   
Case #1: NO Case #2: YES 4 3 4 2 1 2 4 3 4 Case #3: YES 1 2 3 2 3 1 Case #4: YES 1 2 2 3 3 1
 

Source
2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交)
 





#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAX_N=10000;


struct node{
    int num;
    int c;
    friend bool operator<(const node &a,const node &b){
        return a.num<b.num;
    }
};

int T;
node C[30];
int F[10][10];
int n,m,k;
int main(){
    cin>>T;
    int t=T;
    while(T--){
        memset(F,0,sizeof(F));
        int flag=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++){
            scanf("%d",&C[i].num);
            C[i].c=i+1;
            if(C[i].num>(n*m+1)/2){
                flag=1;
            }
        }



        if(flag==1){
            printf("Case #%d:\nNO\n",t-T);
            continue;
        }

        sort(C,C+k);
        /*
        cout<<"_______________________"<<endl;
        for (int i=0;i<k;i++)
            cout<<C[i].c<<" "<<C[i].num<<endl;

        cout<<"_______________________"<<endl;
        */
        int curc=k-1;

        int head,tail,now;
        head=0;tail=k-1;now=tail;
        int sum=n*m;int b;
        if (n%2==1 && m%2==1) b=0;else b=1;
        while (sum>0){
            for (int i=0;i<=b && i<n;i++)
            {
                int j=b-i;
                if (j>=m) continue;
                sum--;
                F[i][j]=C[now].c;
                C[now].num--;
                if (C[now].num==0)
                {
                    if (now==tail) {now=head;tail--;}
                    else {now=tail;head++;}
                }
            }
            b+=2;
            if (b>n+m-2) {
                if (n%2==1 && m%2==1) b=1;else b=0;
            }
        }

        printf("Case #%d:\nYES\n",t-T);
        for(int i=0;i<n;i++){
            printf("%d",F[i][0]);
            for(int j=1;j<m;j++){
                printf(" %d",F[i][j]);
            }
            putchar(10);
        }
    }
    return 0;
}



你可能感兴趣的:(hdu5113 贪心搜索 2014ACM/ICPC亚洲区北京站 B题 Black And White)