zoukankan      html  css  js  c++  java
  • 斗地主(codevs 4610)

    题目描述 Description

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

    输入描述 Input Description

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

    输出描述 Output Description

    输出文件名为 landlords.out。
    共 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

    数据范围及提示 Data Size & Hint

    测试点, 我们约定手牌组数 与张数 的规模如下:
    测试点编号  T    n

    1 100 2 |11 100 14
    2 100 2 |12 100 15
    3 100 3 |13 10 16
    4 100 3 |14 10 17
    5 100 4 |15 10 18
    6 100 4 |16 10 19
    7 100 10 |17 10 20
    8 100 11 |18 10 21
    9 100 12 |19 10 22

    #include<cstdio>  
    #include<cstring>  
    #include<iostream>
    #define M 18
    using namespace std;  
    int n,x[M],cnt[5],ans;  
    int read()
    {
        char c=getchar();int num=0;
        while(c<'0'||c>'9'){c=getchar();}
        while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
        return num;
    } 
    int calc()//先把能带着出的都出上 
    {  
        memset(cnt,0,sizeof(cnt));  
        int res=0;  
        for(int i=0;i<M;i++)cnt[x[i]]++; //cnt[i]表示出现i次的数有几个 
        while(cnt[4]&&cnt[2]>=2) res++,cnt[4]--,cnt[2]-=2; //四带两对 
        while(cnt[4]&&cnt[1]>=2) res++,cnt[4]--,cnt[1]-=2; //四带二 
        while(cnt[3]&&cnt[2]>=1) res++,cnt[3]--,cnt[2]-=1; //三带一对 
        while(cnt[3]&&cnt[1]>=1) res++,cnt[3]--,cnt[1]-=1; //三带一 
        return res+cnt[1]+cnt[2]+cnt[3]+cnt[4]; //统计出当前答案 
    }  
    inline void dfs(int step) 
    {  
        if(step>ans) return;
        //每更新一个状态之前,判断当前状态先出“n带m”是否更优 
        ans=min(ans,step+calc()); 
        //三顺子
        for(int i=2;i<=M;i++)//最小从3开始 
        {  
            int j;
            for(j=i;x[j]>=3;j++);//可以确保 i~j-1 之间所有数字的数量都>=3  
            if(j-i>=2)//至少连续2个 
            {  
                for(int t=j;t-i>=2;t--)//从j枚举结束位置 
                {  
                    for(int k=i;k<t;k++) x[k]-=3;  
                    dfs(step+1);  
                    for(int k=i;k<t;k++) x[k]+=3;//回溯  
                }  
            }  
        }
        //双顺子  
        for(int i=2;i<=M;i++) 
        {  
            int j;
            for(j=i;x[j]>=2;j++);  
            if(j-i>=3) 
            {  
                for(int t=j;t-i>=3;t--) 
                {  
                    for(int k=i;k<t;k++) x[k]-=2;  
                    dfs(step+1);  
                    for(int k=i;k<t;k++) x[k]+=2;  
                }  
            }  
        }
        //单顺子 
        for(int i=2;i<=M;i++) 
        {  
            int j;
            for(j=i;x[j]>=1;j++);  
            if(j-i>=5) 
            {  
                for(int t=j;t-i>=5;t--) 
                {  
                    for(int k=i;k<t;k++) x[k]-=1;  
                    dfs(step+1);  
                    for(int k=i;k<t;k++) x[k]+=1;  
                }  
            }  
        }  
    }  
    int main() 
    {  
        int T=read(),n=read();  
        while(T--) 
        {  
            memset(x,0,sizeof(x));  
            for(int i=1;i<=n;i++) 
            {  
                int w=read(),c=read();  
                if(w==1) w=13;//把A转成13,其余数字减1 
                else if(w) w--;  
                x[w]++;  //统计每个数字的个数 
            }
            ans=calc();  
            dfs(0);
            printf("%d
    ", ans);  
        }  
        return 0;  
    } 
    View Code
  • 相关阅读:
    [TJOI2013]单词 AC 自动机
    NOIP 2017 逛公园 记忆化搜索 最短路 好题
    [BJWC2012]冻结 分层图最短路
    dijkstra STL 堆优化
    [POI2002][HAOI2007]反素数 数论 搜索 好题
    bzoj 2456: mode 思维题 好题
    [SDOI2012]Longge的问题 欧拉反演_欧拉函数
    [JLOI2011]飞行路线 分层图最短路
    页面加速优化
    制作html5微信页面的经验总结。
  • 原文地址:https://www.cnblogs.com/harden/p/5722977.html
Copyright © 2011-2022 走看看