ACM学习历程—Hihocoder 1177 顺子(模拟 && 排序 && gcd)(hihoCoder挑战赛12)

 

时间限制:6000ms

单点时限:1000ms

内存限制:256MB

 

描述

你在赌场里玩梭哈,已经被发了4张牌,现在你想要知道发下一张牌后你得到顺子的概率是多少?

假定赌场使用的是一副牌,四种花色的A、2、3、...、J、Q、K共52张,这副牌只发给你了4张,你的剩下一张牌从剩下48张中任意取出一张。

顺子指的是点数连续的五张牌,包括10、J、Q、K、A这种牌型(不包含同花顺,即构成顺子的五张牌花色不能相同)。参见:https://zh.wikipedia.org/wiki/%E6%92%B2%E5%85%8B%E7%89%8C%E5%9E%8B#.E7.89.8C.E5.9E.8B

输入

一行四个被空格隔开的长度为2或3的字符串,XY,表示你手里的牌。

X为2~10、J、Q、K、A中一个,表示点数,Y为S、H、C、D分别表示黑桃、红心、梅花和方块。

输出

一行一个分数表示概率,注意你的分数需为最简分数,若答案为0输出0/1。

样例输入

10S JS QS KD

样例输出

1/6

 

题目是个模拟,只用暴力枚举每一张牌即可。

最后答案gcd处理公约数以后输出。

 

代码:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long

using namespace std;

struct Card
{
    int num;
    char kind;
};

bool cmp(Card a, Card b)
{
    return a.num < b.num;
}

struct node
{
    Card card[5];
}my;

int ans;

//GCD
//求最大公约数
//O(logn)
int gcd(int a, int b)
{
    if (b == 0)
        return a;
    else
        return gcd(b, a%b);
}

bool input()
{
    char str[5];
    for (int i = 0; i < 4; ++i)
    {
        if (scanf("%s", str) == EOF)
            return false;
        if (strlen(str) == 2)
        {
            if ('2' <= str[0] && str[0] <= '9')
                my.card[i].num = str[0] - '0';
            else if (str[0] == 'A')
                my.card[i].num = 1;
            else if (str[0] == 'J')
                my.card[i].num = 11;
            else if (str[0] == 'Q')
                my.card[i].num = 12;
            else if (str[0] == 'K')
                my.card[i].num = 13;
            my.card[i].kind = str[1];
        }
        else
        {
            my.card[i].num = 10;
            my.card[i].kind = str[2];
        }
    }
    return true;
}

bool judge(node t)
{
    if (t.card[0].kind == t.card[1].kind &&
        t.card[1].kind == t.card[2].kind &&
        t.card[2].kind == t.card[3].kind &&
        t.card[3].kind == t.card[4].kind)
        return false;
    sort(t.card, t.card+5, cmp);
    if (t.card[0].num+1 == t.card[1].num &&
        t.card[1].num+1 == t.card[2].num &&
        t.card[2].num+1 == t.card[3].num &&
        t.card[3].num+1 == t.card[4].num)
        return true;
    if (t.card[0].num == 1 &&
        t.card[1].num+1 == t.card[2].num &&
        t.card[2].num+1 == t.card[3].num &&
        t.card[3].num+1 == t.card[4].num &&
        t.card[4].num == 13)
        return true;
    return false;
}

void work()
{
    ans = 0;
    for (int i = 1; i <= 13; ++i)
    {
        my.card[4].num = i;
        my.card[4].kind = 'S';
        ans += judge(my);
        my.card[4].kind = 'H';
        ans += judge(my);
        my.card[4].kind = 'C';
        ans += judge(my);
        my.card[4].kind = 'D';
        ans += judge(my);
    }
    int d = gcd(ans, 48);
    if (ans == 0)
        printf("0/1\n");
    else
        printf("%d/%d\n", ans/d, 48/d);
}

int main()
{
    //freopen("test.in", "r", stdin);
    while (input())
    {
        work();
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/andyqsmart/p/4575774.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值