zoukankan      html  css  js  c++  java
  • 【NOIP2015】斗地主

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

    P

    Input

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

    Output

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

    Sample Input

    样例输入1: 
    1 8 
    7 4 
    8 4 
    9 1 
    10 4 
    11 1 
    5 1 
    1 4 
    1 1

    样例输入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

    Sample Output

    样例输出1: 
    3

    样例输出2: 
    6

    这个题目可以用贪心搜索解决,对于每次枚举,我们总是先枚举顺子,尽量把牌打的多,之后的最优性剪枝就可以发挥出较大的作用了,
    不过,还是有点难实现,不会的话看看代码吧:
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    using namespace std;
    int num[100];
    int n,t,ans;
    int h[5];
    int suan(){
        int sum=0;
        memset(h,0,sizeof(h));
        for(int i=0;i<=14;i++){
            if(i==1) continue;
            h[num[i]]++;
        }
        while(h[4]>0&&h[2]>1) h[4]--,h[2]-=2,sum++;
        while(h[4]>0&&h[1]>1) h[4]--,h[1]-=2,sum++;
        while(h[3]>0&&h[2]>0) h[3]--,h[2]--,sum++;
        while(h[3]>0&&h[1]>0) h[3]--,h[1]--,sum++;
        return sum+h[4]+h[3]+h[2]+h[1];
    }
    void dfs(int now){
        if(now>=ans) return;
        for(int star=3;star<=14;star++){
            if(num[star]>=3){
                int end=15;
                for(int j=star+1;j<=14;j++) if(num[j]<3) {end=j;break;}
                if(end-star<2) continue;
                for(int k=end-star;k>=2;k--){
                    for(int i=star;i<star+k;i++) num[i]-=3;
                    dfs(now+1);
                    for(int i=star;i<star+k;i++) num[i]+=3;
                }
                }
            }
        for(int star=3;star<=14;star++){
            if(num[star]>=2){
                int end=15;
                for(int j=star+1;j<=14;j++) if(num[j]<2) {end=j;break;}
                if(end-star<3) continue;
                for(int k=end-star;k>=3;k--){
                    for(int i=star;i<star+k;i++) num[i]-=2;
                    dfs(now+1);
                    for(int i=star;i<star+k;i++) num[i]+=2;
                }
                }
            }
        for(int star=3;star<=14;star++){
            if(num[star]>=1){
                int end=15;
                for(int j=star+1;j<=14;j++) if(num[j]<1) {end=j;break;}
                if(end-star<5) continue;
                for(int k=end-star;k>=5;k--){
                    for(int i=star;i<star+k;i++) num[i]-=1;
                    dfs(now+1);
                    for(int i=star;i<star+k;i++) num[i]+=1;
                }
                }
            }
        int tot=suan();
        ans=min(ans,tot+now);
        return;
    }
    int main(){
        cin>>t>>n;
        for(int q=1;q<=t;q++){
            memset(num,0,sizeof(num));
            ans=1<<30;
            for(int i=1;i<=n;i++){
                char x[2],y[2];
                int len;
                cin>>x>>y;
                len=strlen(x);
                if(len==1){
                    if(x[0]=='1') num[14]++;
                    else num[x[0]-'0']++;
                }
                else{
                    if(x[0]=='0') num[0]++;
                    else num[10+x[1]-'0']++;
                }
            }
            dfs(0);
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    JavaScipt面向对象编程----闭包
    vmWare虚拟机下ubuntu配置代理上网
    SimpleDateFormat使用具体解释
    同类型结构体之间赋值不一定有效
    EJB究竟是什么,真的那么神奇吗??
    Python学习笔记12:标准库之对象序列化(pickle包,cPickle包)
    android 视频通话开启呼叫等待后,来第三方的视频通话,接通后通话时间一直显示为0,过几秒之后视频通话自己主动挂断
    [Apache Spark源代码阅读]天堂之门——SparkContext解析
    【Linux】linux经常使用基本命令
    白话经典算法系列之中的一个 冒泡排序的三种实现
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7128190.html
Copyright © 2011-2022 走看看