zoukankan      html  css  js  c++  java
  • UCF Local Programming Contest 2015 H. Reach for the Stars

    https://nanti.jisuanke.com/t/43393

    搜索:以印章的最上面位置为搜索点

    剪枝1:搜索空间去掉第一列、最后一列、最后两行。因为这些位置不能作为印章的最上方

    剪枝2:最优性剪枝

    剪枝3:当此处不作为印章最上面位置时,有些地方永远也覆盖不了了。

    比赛时T飞的原因:

    1、判断可行性时对整个棋局判断,其实每次只会涉及5个位置,判断这5个位置即可

    2、剪枝不到位。剪枝3没想到

    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    int n,m,tot,ans;
    char s[10][10];
    int a[82][2];
    
    
    void dfs(int now,int step,int left)
    {
        if(step+(tot-now+1)/5>=ans) return;
        if(!left)
        {
            ans=step;
            return;
        }
        if(now==tot+1) return;
        char tmp[5];
        int x,y,cnt;
        bool no;
        for(int i=now;i<=tot;++i)
        {
            x=a[i][0];
            y=a[i][1];
            no=false;
            cnt=0;
            tmp[0]=s[x][y];
            tmp[1]=s[x+1][y-1];
            tmp[2]=s[x+1][y];
            tmp[3]=s[x+1][y+1];
            tmp[4]=s[x+2][y];
            for(int j=0;j<5 && !no;++j)
                if(tmp[j]=='.') no=true;
                else if(tmp[j]=='#') cnt++;
            if(!no)
            {
                s[x][y]=s[x+1][y-1]=s[x+1][y]=s[x+1][y+1]=s[x+2][y]='@';
                dfs(i+1,step+1,left-cnt);
                s[x][y]=tmp[0];
                s[x+1][y-1]=tmp[1];
                s[x+1][y]=tmp[2];
                s[x+1][y+1]=tmp[3];
                s[x+2][y]=tmp[4];
            }
            if(s[x][y]=='#') return;
            if(y==2 && s[x+1][1]=='#') return;
            if(y==m-1 && s[x+1][m]=='#') return;
            if(x==n-2 && s[n][y]=='#') return;    
        }
    }
    
    int main()
    {
        int T,sum;
        scanf("%d",&T);
        for(int tt=1;tt<=T;++tt)
        {
            scanf("%d%d",&n,&m);
            tot=sum=0; 
            for(int i=1;i<=n;++i) 
            {
                scanf("%s",s[i]+1);
                for(int j=1;j<=m;++j)
                    if(s[i][j]=='#')
                    {
                        sum++;
                        if(i<=n-2 && j>=2 && j<=m-1) a[++tot][0]=i,a[tot][1]=j;
                    }
            }
            ans=100;
            dfs(1,0,sum); 
            printf("Image #%d: ",tt);
            if(ans==100) printf("impossible
    ");
            else printf("%d
    ",ans);
            if(tt<T) printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    设计模式之设计原则
    把二叉树打印成多行
    快速排序的递归遍历和非递归遍历
    二叉树的非递归遍历
    约瑟夫环问题
    strcpy strcat strcmp memcpy函数的自己实现
    【解题模板】一些很基础的板子
    【笔记】取模运算的用法
    【OJ技巧】DSACPP pa-book中的一些提示
    【编程语言】Java基础进阶——面向对象部分
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12405167.html
Copyright © 2011-2022 走看看