UVa #246 10-20-30 (习题6-9)

86 篇文章 0 订阅

一道朴素的模拟题,有几个地方还是可以留意:

1、一个牌堆的牌全部清空后,牌堆要被移除。我第一反应是链表,不过链表弄起来确实麻烦,其实用vector只要用一个while循环在发牌的时候判断一下牌堆是否为空,为空就挪到下一位就可以了。

2、不必分别判断10、20、30。因为面值最大是10,所以三张牌最多就30。那么只需要判断面值的和除以10的余数是否为零即可

3、关于平局的判断:我用了一个感觉很笨重的方法:自定义了一个struct来储存每次发牌时的快照,并把这些快照装在了一个vector中。感觉应该有更好的办法



Run Time: 0.142s

//  UVa   #6-10.246.cpp

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<stack>
#include<vector>
#include<queue>

#define maxn 500

using namespace std;

struct Status{
    vector<int> pilestatus[7];
    queue<int> deckstatus;
    Status(vector<int> p[7], queue<int> q):deckstatus(q){
        for(int i = 0; i < 7; i ++) pilestatus[i] = p[i];
    }
    bool operator == (const Status& s) const {
        if(s.deckstatus.size() != deckstatus.size()) return false;
        for(int i = 0; i < 7; i ++) {
            if(s.pilestatus[i].size() != pilestatus[i].size()) return false;
            for(int j = 0; j < pilestatus[i].size(); j ++) {
                if(s.pilestatus[i][j] != pilestatus[i][j]) return false;
            }
        }
        queue<int> tempdeckstatus = deckstatus;
        queue<int> stempdeckstatus = s.deckstatus;
        while(!tempdeckstatus.empty()) {
            if(tempdeckstatus.front() != stempdeckstatus.front()) return false;
            tempdeckstatus.pop(); stempdeckstatus.pop();
        }
        return true;
    }
};


//Global Variables.
queue<int> deck;
vector<int> piles[7];
int p, cnt;
vector<Status> statuses;
/

void printPiles();

void clear(queue<int>& q) {
    queue<int> empty;
    swap(q,empty);
}

void checkPile(vector<int>& pile) {
    if(pile.size() >= 3) {
        if((pile[0] + pile[1] + pile[pile.size()-1]) % 10 == 0) {
            deck.push(pile[0]);
            deck.push(pile[1]);
            deck.push(pile[pile.size()-1]);
            for(int i = 0; i < pile.size()-3; i ++)     //Move the subsequent cards 2 pos up
                pile[i] = pile[i+2];
            pile.resize(pile.size()-3);
            checkPile(pile);
        }
        else if((pile[0] + pile[pile.size()-2] + pile[pile.size()-1]) % 10 == 0) {
            deck.push(pile[0]);
            deck.push(pile[pile.size()-2]);
            deck.push(pile[pile.size()-1]);
            for(int i = 0; i < pile.size()-3; i ++)
                pile[i] = pile[i+1];
            pile.resize(pile.size()-3);
            checkPile(pile);
        }
        else if((pile[pile.size()-3] + pile[pile.size()-2] + pile[pile.size()-1]) % 10 == 0) {
            deck.push(pile[pile.size()-3]);
            deck.push(pile[pile.size()-2]);
            deck.push(pile[pile.size()-1]);
            pile.resize(pile.size()-3);
            checkPile(pile);
        }
    }
}

int deal() {
    int i, card;
    for(i = 0; i < 7; i ++, cnt ++) {
        card = deck.front(); deck.pop();
        piles[i].push_back(card);       //Initial Deck.
    }
    p = -1;
    while(1) {
        Status curStatus = Status(piles, deck);
        for(int i = 0; i < statuses.size(); i ++)           //If current status occured before, game's draw
            if(curStatus == statuses[i]) return 0;
        statuses.push_back(curStatus);                      //Record current status.

        card = deck.front(); deck.pop();                    //Retrieve the card to be dealt.
        do{p = (p+1)%7;}while((piles[p]).size() == 0);      //Skip empty piles, locate the pile to be dealt.
        vector<int>& curPile = piles[p];
        curPile.push_back(card);                            //Deal the card.
        cnt ++;
        checkPile(curPile);                                 //Check and pick cards from the dealt pile.
        if(deck.size() == 52) return 1;                     //No piles remaining, game's won.
        if(deck.empty()) return -1;                         //Deck empty, game's lost.
    }
    return -2;
}


int main() {

    int card;
    while(scanf("%d", &card) && card) {
        clear(deck);
        statuses.clear();
        for(int i = 0; i < 7; i ++)
            piles[i].clear();
        p = cnt = 0;
        deck.push(card);

        //Get Deck.
        for(int i = 0; i < 51; i ++) {
            scanf("%d",&card);
            deck.push(card);
        }

        //Deal.
        int result = deal();
        if(result == 0)
            printf("Draw: %d\n", cnt);
        else if(result == 1)
            printf("Win : %d\n", cnt);
        else if(result == -1)
            printf("Loss: %d\n", cnt);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值