2014北京赛区现场赛B hdu 5113 Black And White

来源:互联网 发布:企业局域网监控软件 编辑:程序博客网 时间:2024/06/05 13:28

Black And White

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 ci 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 ci (ci > 0), denoting the number of cells where the i-th color should be used.

It’s guaranteed that c1 + c2 + · · · + cK = 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
41 5 24 13 3 41 2 2 42 3 32 2 23 2 32 2 2
 

Sample Output
Case #1:NOCase #2:YES4 3 42 1 24 3 4Case #3:YES1 2 32 3 1Case #4:YES1 22 33 1
 

题意就是 给定n*m的网络以及k种颜色的棋子  每种颜色的棋子有c[i]个

现在要将这些棋子按要求摆放  具有共同边的即相邻的两个网格不能摆放相同颜色的棋子

问这样的摆放情况是否存在 存在就输出任意一种情况

分析可以知道 如果当前某种棋子的个数大于剩下网格的二分之一 摆放的情况是不存在的

根据这个条件可以对程序进行剪枝优化!!!!

剩下的就是暴搜 在要一个新的点进行摆放棋子时  要判断这个棋子四个方向上的棋子跟它是否是同一种颜色的

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#include <string>#define eps 1e-8#define op operator#define MOD  10009#define MAXN  100100#define INF 0x7fffffff#define MEM(a,x)    memset(a,x,sizeof a)#define ll __int64using namespace std;int n,m,k;//int c[30];int flag;int mp[6][6];int sum;int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};struct node{    int num;//颜色值    int cnt;//当前个数    bool operator<(const node p)const    {        return cnt<p.cnt;    }};node no[30];void dfs(int x,int y,int col){    if(sum==0)    {        flag=1;        puts("YES");        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(j==0)                    printf("%d",mp[i][j]);                else printf(" %d",mp[i][j]);            }            puts("");        }        return;    }    if(flag)  return;    for(int i=1;i<=k;i++)    {        if(no[i].cnt>(sum+1)/2)            return;    }    for(int i=0;i<4;i++)    {        int xx=x+dir[i][0]; int yy=y+dir[i][1];        if(xx<0||xx>=n||yy<0||yy>=m||mp[xx][yy])            continue;        for(int p=1;p<=k;p++)        {            if(!no[p].cnt)                continue;            if(no[p].num==col)                continue;            int f=0;            for(int j=0;j<4;j++)            {                int xxx=xx+dir[j][0]; int yyy=yy+dir[j][1];//                cout<<"no[p].num:"<<no[p].num<<" xxx:"<<xxx<<" yyy:"<<yyy<<" mp:"<<mp[xxx][yyy]<<endl;                if(xxx<0||xxx>=n||yyy<0||yyy>=m)                    continue;                if(mp[xxx][yyy]==no[p].num)                {                    f=1; break;                }            }            if(f)                continue;            mp[xx][yy]=no[p].num;            no[p].cnt--;            sum--;            dfs(xx,yy,no[p].num);            if(flag)                return;            mp[xx][yy]=0;            no[p].cnt++;            sum++;        }    }}int main(){//freopen("ceshi.txt","r",stdin);    int tc;    scanf("%d",&tc);    int cs=1;    while(tc--)    {        scanf("%d%d%d",&n,&m,&k);        for(int i=1;i<=k;i++)        {            scanf("%d",&no[i].cnt);            no[i].num=i;        }        sort(no+1,no+1+k);        sum=n*m;        printf("Case #%d:\n",cs++);        if(no[k].cnt>(sum+1)/2)        {            puts("NO");            continue;        }        flag=0;        MEM(mp,0);        for(int i=1;i<=k;i++)        {            MEM(mp,0);            no[i].cnt--;            mp[0][0]=no[i].num;            sum--;            dfs(0,0,no[i].num);            if(flag)                break;            sum++;            mp[0][0]=0;            no[i].cnt++;        }        if(!flag)            puts("NO");    }    return 0;}





0 0