• 枚举+搜索 hdu-4431-Mahjong


    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4431

    题目大意:

    给一副牌,求出所有能糊的牌。

    解题思路:

    枚举每一张牌,看能不能糊。

    因为一共只有14张牌,每次依据将,去掉三张牌,判断最后两张牌是否一样。

    七对和十三幺单独考虑,

    注意:

    1、1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c 这样的也可以糊9p。

    2、七对时,要为不同的牌,1s 1s 1s 1s 不能糊七对。

    剪枝:

    1、对于不是c色牌,能糊的牌一定出现在手牌或+1,-1同色牌中,所以只用枚举这些可以糊的牌即可。

    2、对于单独的一张牌,左右相邻没有同色牌时,不能糊。

    贴几组测试数据:

    20
    1p 2p 3p 7p 8p 9p 1s 2s 3s 1c 1c 2c 2c
    2 1c 2c
    1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
    2 3m 6m
    1s 2s 3s 2c 2c 2c 2p 3p 5m 6m 7m 1p 1p
    2 1p 4p
    1p 1p 2p 3p 4s 5s 6s 7c 7c 3s 3s 2m 2m
    Nooten
    1p 1p 1p 2p 2p 3p 3p 4p 4p 5p 6p 7p 8p
    6 2p 3p 5p 6p 8p 9p
    1p 2p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m 6m
    2 3p 6p
    1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
    2 3m 6m
    1p 2p 3p 3p 3p 3p 4p 5p 6p 1m 2m 3m 4m
    2 1m 4m
    1c 2c 3c 4c 5c 6c 7c 1p 9p 1m 9m 1s 9s
    13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c
    1p 1p 3p 2p 5p 2p 6p 7p 3p 4p 5p 6p 4p
    3 1p 4p 7p
    1p 1p 2p 3p 2p 3p 4p 4p 5p 5p 6p 7p 7p
    2 3p 6p
    1p 1p 9p 9p 1m 1m 9m 9m 1s 9s 1s 9s 7c
    1 7c
    1p 1p 1p 1p 1m 1m 1m 1s 9s 1c 1c 1s 9s
    Nooten
    1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c
    1 9p

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF 0x1f1f1f1f
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    map<char,int>myp;
    int save[5][15],cnt;
    char sa[5];
    char pp[4]={'m','s','p','c'};
    bool flag,ans[40],hav[40];
    
    void juqi(int a) //判断是否是七对
    {
       for(int i=0;i<34;i++)
       {
          int x=i/9,y=i%9;
          if(!save[x][y])
             continue;
          if(save[x][y]!=2)
             return ;
       }
       //printf("qidui yes
    ");
       ++cnt,ans[a]=true;
       return ;
    }
    void jushi(int a) //判断是否是十三幺
    {
       for(int i=0;i<3;i++)
       {
          if(save[i][0]!=1&&save[i][0]!=2)
             return ;
          if(save[i][8]!=1&&save[i][8]!=2)
             return ;
          for(int j=1;j<8;j++)
             if(save[i][j])
                return ;
       }
       for(int i=0;i<7;i++)
          if(save[3][i]!=1&&save[3][i]!=2)
             return ;
       ++cnt,ans[a]=true;
       return ;
    }
    void dfs(int num,int val)
    {
       if(flag)
          return ;
       if(num==2)
       {
          for(int i=0;i<4;i++)
          {
             for(int j=0;j<=((i==3)?6:8);j++)
                if(save[i][j]==2) //最后两张牌,肯定是一样的才可能糊
                {
                   flag=true;
                   if(!ans[val])
                      ++cnt,ans[val]=true;
                   return ;
                }
                else if(save[i][j])
                   return ;
          }
       }
       for(int i=0;i<4;i++)
       {
          for(int j=0;j<(i==3?7:9);j++)
          {
             if(save[i][j]>=3) //三张一样的牌
             {
                save[i][j]-=3;
                dfs(num-3,val);
                save[i][j]+=3;
                if(flag)
                 return ;
             }
             if(!j||j==8||i==3)
                continue;
             if(save[i][j]&&save[i][j-1]&&save[i][j+1])//连续三张同色牌,注意c牌不行
             {
                save[i][j]--,save[i][j-1]--,save[i][j+1]--;
                dfs(num-3,val);
                save[i][j]++,save[i][j-1]++,save[i][j+1]++;
                if(flag)
                   return ;
             }
          }
       }
    }
    bool iscan()
    {
       for(int i=0;i<3;i++)
       {
          if(save[i][0]==1&&save[i][1]==0)
             return false;
          int j;
          for(j=1;j<=7;j++) //当为只有1张牌,且左右没牌
          {
             if(save[i][j]==1&&save[i][j-1]==0&&save[i][j+1]==0)
                return false;
          }
          if(save[i][j]==1&&save[i][j-1]==0)
             return false;
       }
       for(int i=0;i<7;i++)
          if(save[3][i]==1)
             return false;
       return true;
    }
    int main()
    {
       myp['m']=0,myp['s']=1,myp['p']=2,myp['c']=3;
       int t;
    
       scanf("%d",&t);
       while(t--)
       {
          memset(save,0,sizeof(save));
          memset(ans,false,sizeof(ans));
          memset(hav,false,sizeof(hav));
          for(int i=1;i<=13;i++)
          {
             scanf("%s",sa);
             save[myp[sa[1]]][*sa-'0'-1]++;
             int xx=myp[sa[1]]*9+*sa-'0'-1;
             hav[xx]=true; //hav为能够糊的牌
             if(xx%9) //当然c牌有些不能糊也算进去了,不要紧
             {
                if(xx%9==8)
                   hav[xx-1]=true;
                else
                   hav[xx-1]=hav[xx+1]=true;
             }
             else
                hav[xx+1]=true;
          }
          cnt=0;
          for(int i=0;i<34;i++)
          {
             if(save[i/9][i%9]>=4) //这张牌已经没有了
                continue;
             save[i/9][i%9]++;
             jushi(i);
             if(!hav[i]||!iscan()) //两个剪枝
             {
                save[i/9][i%9]--;
                continue;
             }
             juqi(i);
             flag=false;
             dfs(14,i);
             save[i/9][i%9]--;
          }
          if(!cnt)
          {
             printf("Nooten
    ");
             continue;
          }
          printf("%d",cnt);
          for(int i=0;i<34;i++)
          {
             if(ans[i])
                printf(" %d%c",i%9+1,pp[i/9]);
          }
          putchar('
    ');
       }
       return 0;
    }


  • 相关阅读:
    uni-app引入自己ui写的icon
    2020.07.17
    读uni-app
    图片上传,配置php以及vue简单实现
    vue子给父组件传值
    vue父子传值以及监听这个值,把值拿到子组件使用不报警告
    vue局部跳转,实现一个类似选项卡tab功能
    vuex的一个demo,数据拿到界面上
    vue-day06&day07----路由、路由常用的配置项、vue路由的内置组件、vue路由跳转的方式、路由传值、路由解耦(路由传值的一种方式)、编程式导航、嵌套路由children、路由元信息meta、路由生命周期(路由守卫)、路由懒加载、vue/cli、webpack配置alias、vue/cli中配置alias、vue-router底层原理、单页面开发的缺点、路由报错
    vue-day06----过渡&动画(transition)、axios、axios以post方式请求数据、axios常用的配置项、axios拦截器、qs处理数据、vue中async和await的使用
  • 原文地址:https://www.cnblogs.com/riskyer/p/3266726.html
Copyright © 2020-2023  润新知