• NOIP 2015 斗地主


    题目描述

     牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:

    ""

    输入

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

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

    输出

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

    样例输入

    1 8
    7 4
    8 4
    9 1
    10 4
    11 1
    5 1
    1 4
    1 1
    

    样例输出

    3
    貌似发现了学校测试的规律,每天必须来一个大爆搜,搜搜搜,心累,默默的打完20分特判就不管了。。爆搜搜的是如何出顺子。然后再贪心搞一下其他的什么三带二什么的就好了。

    代码上:

    #include <stdio.h>
    #include <cstring>
    #define Min(x,y) (x)<(y)?(x):(y)
    #define fast __attribute__((optimize("-O3")))
    int T,n,a[31],num[11],Ans;
      
      
    fast inline int read(){
        register int x=0,f=1;
        register char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar());
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
      
    fast inline int __Cooook(){
        memset(num,0,sizeof num);
        register int cnt=0;
        for(register int i=1;i<=14;i++)num[a[i]]++;
        while(num[4]&&num[2]>=2)cnt++,num[4]--,num[2]-=2;
        while(num[4]&&num[1]>=2)cnt++,num[4]--,num[1]-=2;
        while(num[3]&&num[2]>=1)cnt++,num[3]--,num[2]--;
        while(num[3]&&num[1]>=1)cnt++,num[3]--,num[1]--;
        return cnt+num[1]+num[2]+num[3]+num[4];
    }
      
    fast inline int Hash(){
        register int x=read();
        read();
        if(x==0)return 14;
        if(x==1)return 12;
        if(x==2)return 13;
        return x-2;
    }
      
    fast void Cooook(int step){
        if(step>Ans)return;
        Ans=Min(Ans,step+__Cooook());
        for(register int i=1;i<=11;i++){
            register int to=i;
            while(to<=12&&a[to]>=3)to++;to--;
            if(to-i+1<2)continue;
            for(register int k=to;k-i+1>=2;k--){
                for(register int j=i;j<=k;j++)a[j]-=3;
                Cooook(step+1);
                for(register int j=i;j<=k;j++)a[j]+=3;
            }
        }
        for(register int i=1;i<=10;i++){
            register int to=i;
            while(to<=12&&a[to]>=2)to++;to--;
            if(to-i+1<3)continue;
            for(register int k=to;k-i+1>=3;k--){
                for(register int j=i;j<=k;j++)a[j]-=2;
                Cooook(step+1);
                for(register int j=i;j<=k;j++)a[j]+=2;
            }
        }
        for(register int i=1;i<=8;i++){
            register int to=i;
            while(to<=12&&a[to]>=1)to++;to--;
            if(to-i+1<5)continue;
            for(register int k=to;k-i+1>=5;k--){
                for(register int j=i;j<=k;j++)a[j]--;
                Cooook(step+1);
                for(register int j=i;j<=k;j++)a[j]++;
            }
        }
    }
      
    int main(){
        T=read();n=read();
        while(T--){
            memset(a,0,sizeof a);
            for(register int i=1;i<=n;i++)a[Hash()]++;
            Ans = __Cooook();
            Cooook(0);
            printf("%d
    ",Ans);
        }
    }






  • 相关阅读:
    AS将一个项目导入到另一个项目中
    Android Studio出现:Cause: unable to find valid certification path to requested target
    小米手机Toast带app名称
    PopupWindow 点击外部区域无法关闭的问题
    EditText inputType类型整理
    Fragment通过接口回调向父Activity传值
    Android selector一些坑
    Installation failed with message Failed to commit install session 634765663 with command cmd package
    旷视上海研究院机器人方向招聘
    语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738499.html
Copyright © 2020-2023  润新知