zoukankan      html  css  js  c++  java
  • P2668 斗地主

    P2668 斗地主

    题目描述

    牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。

    现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。

    需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。

    具体规则如下:

    输入输出格式

    输入格式:

    第一行包含用空格隔开的2个正整数T和n,表示手牌的组数以及每组手牌的张数。

    接下来T组数据,每组数据n行,每行一个非负整数对aibi表示一张牌,其中ai示牌的数码,bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。

    输出格式:

    共T行,每行一个整数,表示打光第i手牌的最少次数。

    输入输出样例

    输入样例#1:
    1 8
    7 4
    8 4
    9 1
    10 4
    11 1
    5 1
    1 4
    1 1
    输出样例#1:
    3
    
    输入样例#2:
    1 17
    12 3
    4 3
    2 3
    5 4
    10 2
    3 3
    12 2
    0 1
    1 3
    10 1
    6 2
    12 1
    11 3
    5 2
    12 4
    2 2
    7 2
    
    输出样例#2:
    6
    

    说明

    样例1说明

    共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。

    对于不同的测试点, 我们约定手牌组数T与张数n的规模如下:

    数据保证:所有的手牌都是随机生成的。

    分析:深搜。深搜顺子出现的各种情况,然后加上 三带一,三带二,四带一,四带二,四带两个对子,单出一张牌,两张牌,三张牌,四张牌的次数

      1 #include<cstdio>
      2 #include<cstring>
      3 
      4 using namespace std;
      5 const int N = 20;
      6 
      7 int puke[N];
      8 int num[N];
      9 int t,n,ans;
     10 
     11 int chupai()
     12 {
     13     memset(num,0,sizeof(num));
     14     for(int i=0;i<=13;++i)
     15         num[puke[i]]++;
     16     int tot = 0;
     17     while(num[4] && num[2]>1)
     18     {
     19         num[4]--;
     20         num[2] -= 2;
     21         tot++; 
     22     }
     23     while(num[4] && num[1]>1)
     24     {
     25         num[4]--;
     26         num[1] -= 2;
     27         tot++;
     28     }
     29     while(num[4] && num[2])
     30     {
     31         num[4]--;
     32         num[2]--;
     33         tot++;
     34     }
     35     while(num[3] && num[2])
     36     {
     37         num[3]--;
     38         num[2]--;
     39         tot++;
     40     }
     41     while(num[3] && num[1])
     42     {
     43         num[3]--;
     44         num[1]--;
     45         tot++;
     46     }
     47     return tot + num[1] + num[2] + num[3] + num[4];
     48 }
     49 
     50 void dfs(int step)
     51 {
     52     if(step>=ans) return;
     53     int tmp = chupai();
     54     if(tmp+step<ans) ans = tmp+step;
     55     for(int i=2;i<=13;++i)    //三个的顺子 
     56     {    
     57         int j = i;
     58         while(puke[j]>=3) j++;
     59         if(j-i>=2)
     60             for(int p=i+1;p<=j-1;++p)
     61             {
     62                 for(int k=i;k<=p;++k)
     63                     puke[k] -= 3;
     64                 dfs(step+1);
     65                 for(int k=i;k<=p;++k)
     66                     puke[k] += 3;
     67             }
     68     }
     69     for(int i=2;i<=13;++i)    //两个的顺子 
     70     {    
     71         int j = i;
     72         while(puke[j]>=2) j++;
     73         if(j-i>=3)
     74             for(int p=i+2;p<=j-1;++p)
     75             {
     76                 for(int k=i;k<=p;++k)
     77                     puke[k] -= 2;
     78                 dfs(step+1);
     79                 for(int k=i;k<=p;++k)
     80                     puke[k] += 2;
     81             }
     82     }
     83     for(int i=2;i<=13;++i)    //一个的顺子 
     84     {    
     85         int j = i;
     86         while(puke[j]>=1) j++;
     87         if(j-i>=5)
     88             for(int p=i+4;p<=j-1;++p)
     89             {
     90                 for(int k=i;k<=p;++k)
     91                     puke[k]--;
     92                 dfs(step+1);
     93                 for(int k=i;k<=p;++k)
     94                     puke[k]++;
     95             }
     96     }
     97 }
     98 int main()
     99 {
    100     freopen("landlords.in","r",stdin);
    101     freopen("landlords.out","w",stdout);
    102     scanf("%d%d",&t,&n);
    103     while(t--)
    104     {
    105         memset(puke,0,sizeof(puke));
    106         for(int i=1;i<=n;++i)
    107         {
    108             int x,y;
    109             scanf("%d%d",&x,&y);
    110             if(x==1) x = 13;
    111             else if(x) x--;
    112             puke[x]++;
    113         }
    114         ans = 99999999;
    115         dfs(0);
    116         printf("%d
    ",ans);
    117     }
    118     return 0;
    119 } 
  • 相关阅读:
    迭代器生成器和协程函数
    装饰器
    对haproxy.conf文件的增删改查
    函数基础
    深入理解python字符编码
    python字符串列表字典常用方法
    委托的使用
    数据库连接
    输入输出流
    泛型集合的使用
  • 原文地址:https://www.cnblogs.com/mjtcn/p/6891513.html
Copyright © 2011-2022 走看看