首页 > ACM题库 > HDU-杭电 > hdu 2400 Bridge Bidding[解题报告]C++
2014
01-26

hdu 2400 Bridge Bidding[解题报告]C++

Bridge Bidding

问题描述 :

Bridge is a very complicated card game, and the bidding part is particularly difficult to master. The bidding is made even more difficult because players use different bidding conventions (meanings assigned to bids). In this problem, you are asked to write a program that suggests the first bid that should be made. The bidding conventions described below are simplified from those used by a certain person who shall remain nameless.A bridge hand consists of 13 cards. Each card has a suit (spades, hearts, diamonds, or clubs) and a rank (A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2). Here, the letter T denotes the card whose rank is 10. Before making a bid, an experienced bridge player studies the number of high card points (hcp) in the hand, as well as the distribution (the number of cards in each suit). The hcp contributed by each card is completely determined by its rank as follows:

Rank hcp
A 4
K 3
Q 2
J 1
Others 0

For example, if the hand is:

Spades: A, 2
Hearts: K, J, T, 9, 2
Diamonds: 3
Clubs: K, Q, 7, 4, 3

Then this hand has 13 hcp and a distribution of 5-5-2-1 (the distribution is usually listed in non-increasing order). A balanced distribution is any one of 4-3-3-3, 4-4-3-2, and 5-3-3-2.

In bridge, an opening bid is either “pass” or consists of a level (1-7) and a trump suit. The trump suits are no trump, spades, hearts, diamonds, clubs ranked in decreasing order. Once a hand has been evaluated, the player applies the following list of (simplified) rules to determine the appropriate opening bid. In cases where multiple rules apply, the first one that applies should be used. An “x” in a distribution can be substituted with any non-negative number. Multiple “x”s in a distribution are not necessarily the same.

1. With at least 10 hcp and a y-x-x-x distribution (y >= 8), bid the suit with y cards at the 4 level. This is known as a preemptive bid.
2. With 10-13 hcp and a 7-x-x-x distribution, bid the suit with 7 cards at the 3-level. This is known as a preemptive bid.
3. With 8-9 hcp and a y-x-x-x distribution (y >= 7), bid the suit with y cards at the 2-level if the y-card suit is Spades or Hearts. This is known as a “weak-two” bid.
4. With 8-11 hcp and a 6-x-x-x distribution, in which Spades or Hearts is one of the 6-card suits, bid the higher rank suit at the 2 level. This is known as a “weak-two” bid.
5. With 11-15 hcp, a distribution of 4-4-4-1 or 5-4-4-0, and at least 4 spades, bid Diamonds at the 2 level. This is called the “Mini Roman Convention”.
6. With 15-17 hcp and a balanced distribution, bid No Trump at the 1 level provided that at least 3 suits are “stopped.” A suit is considered stopped if the suit contains at least one of the following:

an A;
a K and one other;
a Q and two others; or
a J and three others;

7. With 20-22 hcp and a balanced distribution, bid No Trump at the 2 level.
8.With at least 22 hcp, bid Clubs at the 2 level.
9. With 13-16 hcp:
a. If there is a 5-card or longer suit in Spades or Hearts, bid it at the 1 level. If both bids are possible, bid the longer suit. If both suits have the same length, bid the higher ranking suit.
b. Without a 5-card suit in Spades or Hearts, bid the longer of Diamonds or Clubs at the 1 level (whichever one has the most number of cards) . If there is a tie, bid the higher ranking suit.

10. With at least 17 hcp, bid the longest suit at the 1 level. If there is a tie, bid the lowest ranking suit. This is known as a “reverse”.
11. If none of the rules above is applicable, bid Pass.

In the example above, rule 9a applies and a bid of 1 Hearts should be made.

输入:

The input consists of a number of cases. The bridge hand for each case is specified on one line, with a single space separating each of the 13 cards in the hand. Each card is given as a two-character string. The first letter is the suit (S, H, D, C) and the second character is the rank (A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2). The end of input is terminated by end-of-file.

输出:

The input consists of a number of cases. The bridge hand for each case is specified on one line, with a single space separating each of the 13 cards in the hand. Each card is given as a two-character string. The first letter is the suit (S, H, D, C) and the second character is the rank (A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2). The end of input is terminated by end-of-file.

样例输入:

SA S2 HK HJ HT H9 H2 D3 CK CQ C7 C4 C3
SK SQ HT H8 H4 CA CQ CT C5 DK DQ DJ D8
SA SK SQ S3 S2 HT D7 D9 CA CK CQ C7 C5

样例输出:

Hand #1: 1 Hearts
Hand #2: 1 No Trump
Hand #3: 1 Clubs


G++AC代码:

#include "iostream"
#include "algorithm"
#include "cstdio"
#include "cstdlib"
#include "cstring"
#include "iterator"
using namespace std;
#define $FOREACH(a, b) for(__typeof(b.begin())a=b.begin(), a##ed__=b.end(); a!=a##ed__; a++)
#define $FOREACHC(a, b, cond)   for (__typeof(b) a=b;(cond); b++, a=b)
#define $QUEUEPROC(cond, U, V) \
    for(int u=(U);cond;u=(U))\
        $FOREACH(v, V)  
#define $STACKPROC(cond, U, V) \
    for (int u=(U); cond; u=(U))\
        for (bool child=false; !child; child=true)\
            $FOREACHC(v, (V), !child)
#define $ASSERT(a) ({fprintf(stderr,"%s:%d: %s\n", __FILE__, __LINE__, #a); exit(-1);})

char* rank = "  23456789TJQKA";
char* suit = "SHDC";

int revers[256];
int rev[256];
int card[200];

int tot=0;
int dist[4];
int ihcp[15];
inline void pre()
{
    for (int i=0; i<15; i++) revers[(int)rank[i]]=i, 
                 ihcp[i] = (i>10?i-10:0);         
    for (int i=0; i<4;  i++) rev[(int)suit[i]]=i;
}
int hcp;
bool read()
{
    char s[1024];
    if (!gets(s)) return false;
    fill(dist, dist+4, 0);
    hcp=0;
    for (int i=0, j=0; j<13; i+=3, j++)
    {

        card[j] = rev[(int)s[i]] * 20 + revers[(int)s[i+1]],
        dist[rev[(int)s[i]]]++,
        hcp+=ihcp[revers[(int)s[i+1]]];
    }
    return true;
}
char suits[][1000]={
    "Spades",
    "Hearts",
    "Diamonds",
    "Clubs",
    "No Trump",
    "Pass",
};
inline void bid(int level, int suit)
{
    static int ncase = 0;
    if (suit < 5)
        printf("Hand #%d: %d %s\n", ++ncase, level, suits[suit]);
    else
        printf("Hand #%d: %s\n", ++ncase, suits[suit]);
}

inline bool check(int *z, int a, int b, int c, int d)
{
    if (z[0] != a || z[1]!=b || z[2]!=c || z[3]!=d) return false;
    return true;
}

inline bool stopped(int *dist)
{
    int stop = 0;
    for (int i=0; i<4; i++)
    {
        if (
                find(card, card+13, i*20+14)!=card+13 ||
                find(card, card+13, i*20+13)!=card+13 && dist[i]>1||
                find(card, card+13, i*20+12)!=card+13 && dist[i]>2||
                find(card, card+13, i*20+11)!=card+13 && dist[i]>3
        ) stop++;
    }
    return stop>=3;
}

int main()
{
    pre();
    while (read())
    {
        int r = find(dist, dist+4, *max_element(dist, dist+4))-dist;
        int m = dist[r];
        #ifdef Debug
        for (int i=0; i<4; i++) printf("%d ", dist[i]);
        puts("");
        printf("%d %d %d\n", m, r, hcp);
        #endif
        int z[4];
        copy(dist, dist+4, z);
        sort(z, z+4, greater<int>());
        if (hcp >= 10 && m>=8)
            bid(4, r);
        else if (hcp >= 10 && hcp <= 13 && m == 7)
            bid(3, r);
        else if (hcp >= 8 && hcp <= 9 && (dist[0] >= 7 || dist[1]>=7))
        {
            if (dist[1] < 7 || dist[0] >= dist[1])
                bid(2, 0);
            else
                bid(2, 1);
        }
        else if (hcp >= 8 && hcp <= 11  && (dist[0]>=6 || dist[1]>=6))
        {
            if (dist[1] < 6 || dist[0] >= dist[1])
                bid(2, 0);
            else
                bid(2, 1);
        }
        else if (hcp >= 11 && hcp <= 15 && 
                (check(z,4,4,4,1)||check(z, 5,4,4,0))
                && dist[0] >= 4)
            bid(2, 2);
        else if (hcp >=15 && hcp <= 17 && 
                (check(z, 4,3,3,3) || check(z, 4,4,3,2) || check(z,5,3,3,2))&&
                stopped(dist))
            bid(1, 4);
        else if (hcp >= 20 && hcp <= 22 && (check(z, 4,3,3,3) || check(z, 4,4,3,2) || check(z,5,3,3,2)))
            bid(2, 4);
        else if (hcp >= 22)
            bid(2, 3);
        else if (hcp >= 13 && hcp <= 16 && (dist[0]>=5 || dist[1]>=5))
        {
            if (dist[1] < 5 || dist[0] >= dist[1])
                bid(1, 0);
            else
                bid(1, 1);

        }
        else if (hcp >= 13 && hcp <= 16)
            if (dist[2] >= dist[3])
                bid(1, 2);
            else
                bid(1, 3);

        else if (hcp >= 17)
        {
            for (int i=3; i>=0; i--)
                if (dist[i] == m)
                {
                    bid(1, i);
                    break;
                }
        }
        else
            bid(0, 5);
    }
}

 


  1. 思路二可以用一个长度为k的队列来实现,入队后判断下队尾元素的next指针是否为空,若为空,则出队指针即为所求。

  2. Thanks for taking the time to examine this, I really feel strongly about it and love studying a lot more on this topic. If possible, as you acquire experience

  3. 站长好。我是一个准备创业的互联网小白,我们打算做一个有关国*际*游*学的平台。手上也有了一些境外资源。现阶段的团队现在没有cto.原意出让一些管理股寻找一个靠谱的技术专家做合伙人, 不知道是不是能得到您的帮助。发个帖子或者其他方式。期待您的回应。可以加我微信tianxielemon聊聊。

  4. 站长,你好!
    你创办的的网站非常好,为我们学习算法练习编程提供了一个很好的平台,我想给你提个小建议,就是要能把每道题目的难度标出来就好了,这样我们学习起来会有一个循序渐进的过程!