uva 246 5185 10-20-30

来源:互联网 发布:linux 高精度时钟 编辑:程序博客网 时间:2024/06/05 07:34

10-20-30

A simple solitaire card game called 10-20-30 uses a standard deck of 52playing cards in which suit is irrelevant. The value of a face card (king,queen, jack) is 10. The value of an ace is one. The value of each of theother cards is the face value of the card (2, 3, 4, etc.). Cards are dealtfrom the top of the deck. You begin by dealing out seven cards, left toright forming seven piles. After playing a card on the rightmost pile, thenext pile upon which you play a card is the leftmost pile.

For each card placed on a pile, check that pile to see if one of thefollowing three card combinations totals 10, 20, or 30.

  1.  the first two and last one,

2. the first one and the last two, or

3. the last three cards.

If so, pick up the three cards and place them on the bottom of the deck. Forthis problem, always check the pile in the order just described. Collect thecards in the order they appear on the pile and put them at the bottom of thedeck. Picking up three cards may expose three more cards that can be pickedup. If so, pick them up. Continue until no more sets of three can be pickedup from the pile.

For example, suppose a pile contains 5 9 7 3 where the 5 is at the firstcard of the pile, and then a 6 is played. The first two cards plus the lastcard (5 + 9 + 6) sum to 20. The new contents of the pile after picking upthose three cards becomes 7 3. Also, the bottommost card in the deck is nowthe 6, the card above it is the 9, and the one above the 9 is the 5.

If a queen were played instead of the six, 5 + 9 + 10 = 24, and 5 + 3 + 10 =18, but 7 + 3 + 10 = 20, so the last three cards would be picked up, leavingthe pile as 5 9.

If a pile contains only three cards when the three sum to 10, 20, or 30,then the pile "disappears" when the cards are picked up. That is, subsequentplay skips over the position that the now-empty pile occupied. You win ifall the piles disappear. You lose if you are unable to deal a card. It isalso possible to have a draw if neither of the previous two conditions everoccurs.

Write a program that will play games of 10-20-30 given initial card decks asinput

input

Each input set consists of a sequence of 52 integers separated by spacesand/or ends of line. The integers represent card values of the initial deckfor that game. The first integer is the top card of the deck. Input isterminated by a single zero (0) following the last deck.

output

For each input set, print whether the result of the game is a win, loss, ora draw, and print the number of times a card is dealt before the gameresults can be determined. (A draw occurs as soon as the state of the gameis repeated.) Use the format shown in the ``Sample Output"section.

simple input

2 6 5 10 10 4 10 10 10 4 5 10 4 5 10 9 7 6 1 7 6 9 5 3 10 10 4 10 9 2 110 1 10 10 10 3 10 9 8 10 8 7 1 2 8 6 7 3 3 8 24 3 2 10 8 10 6 8 9 5 8 10 5 3 5 4 6 9 9 1 7 6 3 5 10 10 8 10 9 10 10 72 6 10 10 4 10 1 3 10 1 1 10 2 2 10 4 10 7 7 1010 5 4 3 5 7 10 8 2 3 9 10 8 4 5 1 7 6 7 2 6 9 10 2 3 10 3 4 4 9 10 1 110   5 10 10 1 8 10 7 8 10 6 10 10 10 9 6 2 10 100

simple output

Win : 66Loss: 82Draw: 73题目:一种只纸牌游戏叫做10-20-30,共有52张牌,不考虑花色,K、Q、J的值看做10,其它牌的值看做纸牌的数值,从牌堆顶部开始发牌。先发七张牌,从左到右形成七组。给最右边的那组发完牌后再给最左边的发牌。如果牌堆中出现了一下状况:前两张和最后一张纸牌的总值或者第一张和最后两张纸牌的总值或者最后三张纸牌的总值为10、20或者30,则抽出这三张牌将其放到牌堆底部。如果有一组牌堆只含有三张牌,且他们的总值为10、20、30则抽出这些牌,最后发牌将跳过这一位置,若所有的牌堆都消失了,则赢,当无牌发的时候,输,否则平;输入:输入52张牌的面值输出:胜负结果及所发的牌数;/********************************************************************************************************************************************************//*************************************************手残将书上的例题自己照着打了一遍**************************************************************************//******************************************************************************************************************************************************/代码:
#include <bits/stdc++.h>#define p 1999997///hash1的模值#define p2 10000009///hash2的模值using namespace std;bool h[2100000];///标志函数hash的值为f的状态已经出现int key[2100000];string s;///储存当前状态int a[60],n;char sign[10];///定位标志bool v[10];int num(char c)///将纸牌转化为面值{    if(c=='0')        return 10;    return c-'0';}int ch(int x)///将面值转化为纸牌符号{    if(x==10)        return '0';    return '0'+x;}int l(int i)///找出第i个牌堆中第一张牌的地址值{    return s.find(sign[i])+1;}int r(int i)///找出第i个牌堆中最后一张牌的地址{    return s.find(sign[i+1])-1;}/***********************************************/int hash(string s)///计算s的哈希值:(除留余数法){    int f=0,i;    for(i=0; i<=s.size()-1; i++)        f=(f*13+s[i]-'0')%p;    return f;}int hash2(string s)///求s的判重函数值hash2(???不知为什么???){    int f2=0,i;    for(i=0; i<=s.size()-1; i++) f2=(f2*13+s[i]-'0')%p2;    return f2;}bool have(string s)///判断s状态在哈希表中出现过没有,如果未出现则加到哈希表中并返回0,否则返回1;{    int f=hash(s),f2=hash2(s);    while(h[f]&&(key[f]!=f2)) f++;///key[f]表示哈希值为f的状态的hash2值    if(!h[f])///判断是否出现过(由h[f]标记)    {        h[f]=1;        key[f]=f2;        return 0;    }    return 1;}/******************************************************/void initialize()///初始化函数{    s.clear();    char c='A';    int i;    for(i=1; i<=n; i++)    {        if(i<=8)        {            s+=c;            sign[i]=c;            c++;        }        s+=ch(a[i]);    }    memset(v,false,sizeof(v));    memset(h,false,sizeof(h));    memset(key,false,sizeof(key));    have(s);///构造s的哈希表(除留余数法)}void remove1(int i)///对于第一种情况抽出牌堆i中的牌{    string t=s.substr(l(i),2);    t+=s.substr(r(i),1);    s+=t;    s.erase(l(i),2);    s.erase(r(i),1);}bool case1(int i)///判断是否为第一种情况{    int sum=num(s[l(i)])+num(s[l(i)+1])+num(s[r(i)]);    if(sum==10||sum==20||sum==30)    {        remove1(i);        return 1;    }    return 0;}void remove2(int i)///抽出第二种情况{    string t=s.substr(l(i),1);    t+=s.substr(r(i)-1,2);    s+=t;    s.erase(l(i),1);    s.erase(r(i)-1,2);}bool case2(int i)///判断是否为第二种情况{    int sum=num(s[l(i)])+num(s[r(i)-1])+num(s[r(i)]);    if(sum==10||sum==20||sum==30)    {        remove2(i);        return 1;    }    return 0;}void remove3(int i)///第三种情况{    string t=s.substr(r(i)-2,3);    s+=t;    s.erase(r(i)-2,3);}bool case3(int i)///判断是否为第三种情况{    int sum=num(s[r(i)-2])+num(s[r(i)-1])+num(s[r(i)]);    if(sum==10||sum==20||sum==30)    {        remove3(i);        return 1;    }    return 0;}void deliver(int i)///给第i个牌堆发牌{    string t=s.substr(l(8),1);///在s中取出手中的牌    s.insert(r(i)+1,t);///插入到第i个牌堆中    s.erase(l(8),1);///释放掉手牌中的第一张    if(r(i)-l(i)>=2)///判断牌堆是否大于3张    {        while(r(i)-l(i)>=2)///若第i堆牌中不少于三张,则处理三种情况        {            bool flag=false;            if(case1(i))continue ;            else if(case2(i)) continue;            else if(case3(i)) continue;            else flag=true;            if(flag)                break;        }    }    if(r(i)<l(i)) v[i]=true;///如果少于三张牌,则让这一牌堆消失(v[i]标志为1)}int over()///判断当前游戏的结果(0表示可以继续游戏,1表示){    int i;    if(have(s))        return 3;    else if(l(8)>=s.size())        return 2;    else        for(i=1; i<=7; i++)            if(!v[i]) return 0;    return 1;}void game()///模拟游戏过程{    int i=1,step=7,res;    while(1)    {        deliver(i);///发牌        step++;        res=over();///取结果        if(res)            break;        i=(i%7)+1;///寻找未消失的下一组纸牌堆?????        while(v[i]) i=(i%7)+1;///??????????    }    switch(res)    {    case 1:        printf("Win : ");        break;    case 2:        printf("Loss: ");        break;    case 3:        printf("Draw: ");    }    printf("%d\n",step);}int main(){    n=52;    int i;    scanf("%d",&a[1]);    while(a[1])    {        for(i=2; i<=n; i++) scanf("%d",&a[i]);        initialize();        game();        cin>>a[1];    }    return 0;}



~~~~(>_<)~~~~ 不懂为啥会想到用哈希,不懂为何用哈希判重。╮(╯▽╰)╭。。。先留着以后再看。↖(^ω^)↗

0 0
原创粉丝点击