ACM/ICPC 14 北京站现场赛 B

// dfs回溯 + 估价函数

#include<cstdio>  
#include<iostream>  
#include<cstring>  
#include<string.h>  
#include<algorithm>  
using namespace std;  
const int maxn = 5 + 5;  
int res[maxn][maxn];  
int cnt[maxn * maxn];  
int n, m, k;  
int flog;  
int ok(int i, int j, int kk)  
{  
    if(i-1 >= 1)  
        if(res[i-1][j] != -1 && res[i-1][j] == kk) return 0;  
    if(i+1 <= n)  
        if(res[i+1][j] != -1 && res[i+1][j] == kk) return 0;  
    if(j-1 >= 1)  
        if(res[i][j-1] != -1 && res[i][j-1] == kk) return 0;  
    if(j+1 <= m)  
        if(res[i][j+1] != -1 && res[i][j+1] == kk) return 0;  
    return 1;  
}  
void dfs(int i, int j, int v)  
{  
    if(i==n && j==m) flog = true;  
    if(flog) return ;  
    for(int i = 1; i <= k; ++i)  
        if((v+1)/2 < cnt[i]) return ;  
    for(int kk = 1; kk <= k; ++kk)  
    {  
        if(!cnt[kk]) continue;  
        if(j==m)  
        {  
            if(ok(i+1, 1, kk))  
            {  
                --cnt[kk];  
                res[i+1][1] = kk;  
                dfs(i+1, 1, v-1);  
                if(flog) return ;  
                res[i+1][1] = -1;  
                ++cnt[kk];  
            }  
        }  
        else  
        {  
            if(ok(i, j+1, kk))  
            {  
                --cnt[kk];  
                res[i][j+1] = kk;  
                dfs(i, j+1, v-1);  
                if(flog) return ;  
                res[i][j+1] = -1;  
                ++cnt[kk];  
            }  
        }  
    }  
    return ;  
}  
int main()  
{  
    int T;  
    scanf("%d", &T);  
    int kase = 0;  
    while(T--)  
    {  
        printf("Case #%d:\n", ++kase);  
        scanf("%d%d%d", &n, &m, &k);  
        memset(cnt,0,sizeof(cnt));  
        memset(res,-1,sizeof(res));  
        for(int i = 1; i <= k; ++i) scanf("%d", &cnt[i]);  
        flog = false;  
        dfs(1, 0, n*m);  
        if(flog)  
        {  
            cout << "YES" << endl;  
            for(int i = 1; i <= n; ++i)  
            {  
                for(int j = 1; j <= m; ++j)  
                {  
                    if(j==1) printf("%d", res[i][j]);  
                    else printf(" %d", res[i][j]);  
                }  
                printf("\n");  
            }  
        }  
        else cout << "NO" << endl;  
    }  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值