dfs减枝回溯! HDU 5113

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int yy[60];
int g[30][30];
bool jud(int x,int y,int i){
    if(x<0||x>=n||y<0||y>=m) return true;
    if(g[x][y]!=i) return true;
    return false;
}
bool Cut(int step)
{
    int le = (n*m-step+1)/2;
    for(int i=0;i<k;i++)
    {
        if(le<yy[i]) return true;
    }
    return false;
}
bool dfs(int x,int y,int step){
    if(x==n) return true;
    if(y==m)  return dfs(x+1,0,step);
    if(Cut(step)) return false;
    for(int i=0;i<k;i++) if(yy[i])
    {
        int x1=x-1,y1=y;
        int x2=x,y2=y-1;
        if( jud(x1,y1,i)&&jud(x2,y2,i) )
        {
            yy[i]--;
            g[x][y]=i;
            if(dfs(x,y+1,step+1)) return true;
            yy[i]++;
        }
    }
    return false;
}
int main()
{
    int t,kase=0;scanf("%d",&t);
    while(t--){
        memset(g,0,sizeof(g));
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++) scanf("%d",&yy[i]);
        printf("Case #%d:\n",++kase);
        if(dfs(0,0,0)){
            printf("YES\n");
            for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(j==0) printf("%d",g[i][j]+1);
            else printf(" %d",g[i][j]+1);

        }

        printf("\n");
        }
        }
        else printf("NO\n");


    }
    return 0;
}

比赛时想的是下面这种方法

还是有一步没想到

先填奇数格子后填偶数格子

样例不过

后换先偶后积 后来全加上还是wrong

所以填颜色的顺序还是有问题的

因该按照最多最少次多次少的顺序填

看一组样例就会明白

3 3 3

1 4 4

这组样例,按有颜色多到少排是不对的

有的题解说的四个方向也就是分横和列的奇数偶数

只判横也是能过的

#include<bits/stdc++.h>
using namespace std;
int num[60];
struct xx{
    int ID,num;
    bool operator <(const xx&rhs) const {
        return num>rhs.num;
    }
}Y[60],YY[60];
int YYY[60];
int a[30][30];
int main()
{
    int t,kase=0;scanf("%d",&t);
    while(t--){
            memset(a,-1,sizeof(a));
        memset(Y,0,sizeof(Y));
        memset(YY,0,sizeof(YY));
        int n,m,k;scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++) { scanf("%d",&Y[i].num); Y[i].ID=i; }
        sort(Y,Y+k);
//        printf("####:");
//        for(int i=0;i<k;i++) printf("%d ",Y[i].num); printf("\n");
        int y1=0,y2=k-1;//printf("***:");
        for(int i=0;i<k;i++)
        {
            if(i%2==0)
            YY[i]=Y[y1++];
            else YY[i]=Y[y2--];
            //printf("%d ",YY[i].num);
            //printf("ID[%d] ",YY[i].ID);
        }//printf("\n");
        int J=0;
        for(int i=0;i<k;i++) {
            while(YY[i].num--)
            YYY[J++] = YY[i].ID;}
//        printf("YYYY:");
//        for(int i=0;i<n*m;i++) printf("%d ",YYY[i]); printf("\n");
        int K=0;
        for(int i=0;i<n;i++){
            if( !( i&1)  )
           {
               for(int j=0;j<m;j+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int j=1;j<m;j+=2)  a[i][j]=YYY[K++]; }
        }


        for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }


        int flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }
            if(flag==0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int i=0;i<n;i++){
            if( !( i&1)  )
           {
               for(int j=1;j<m;j+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int j=0;j<m;j+=2)  a[i][j]=YYY[K++]; }
        }


        for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }


         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            if(flag==0&&0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int j=0;j<m;j++){
            if( !( j&1)  )
           {
               for(int i=1;i<n;i+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int i=0;i<n;i+=2)  a[i][j]=YYY[K++]; }
        }


        for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }


         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            if(flag==0&&0){
                    memset(a,-1,sizeof(a));
                flag=1;
                int K=0;
        for(int j=0;j<m;j++){
            if( !( j&1)  )
           {
               for(int i=0;i<n;i+=2)  a[i][j]=YYY[K++];
           }
            else
            { for(int i=1;i<n;i+=2)  a[i][j]=YYY[K++]; }
        }


        for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
       {

           if(a[i][j]==-1){
            a[i][j]=YYY[K++];
           }
       }
        }


         flag=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                {

                    if(j+1<m&&a[i][j]==a[i][j+1]) { flag=0; break; }
                    if(j-1>=0&&a[i][j]==a[i][j-1]) { flag=0; break; }
                    if(i+1<n&&a[i][j]==a[i+1][j]) { flag=0; break; }
                    if(i-1>=0&&a[i][j]==a[i-1][j]) { flag=0; break; }
                }
                if(flag==0 ) break;
            }

            }
            printf("Case #%d:\n",++kase);
            if(flag) {
                printf("YES\n");
//                printf("^^^^^^\n");
             for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                        if(j==0)
                 printf("%d",a[i][j]+1);
                else printf(" %d",a[i][j]+1);
                }
                printf("\n");
                }
//                printf("^^^^^^\n");
            }
            else printf("NO\n");

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值