uva 246 - 10-20-30(双端队列+模拟)

737 篇文章 0 订阅

题目链接:uva 246 - 10-20-30

题目大意:一个人在玩纸牌游戏,给定牌的顺序,轮流为7堆牌发牌。

  • 如果满足条件,可以一直收取堆上的3张牌,直到不满足为止
  • 如果牌堆出现空的情况,那么以后的发牌将跳过这个牌堆(初始不算)
    求在第几步可以确定游戏的状态:胜利,失败,循环

解题思路:用8个双端队列模拟即可。

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
typedef deque<int> deq;
const char sign[3][10] = {"Draw:", "Loss:", "Win :"};

int step;
vector<deq> s;

bool judge_end () {
    for (int i = 1; i <= 7; i++)
        if (!s[i].empty())
            return false;
    return true;
}

bool init () {
    int x;
    deq u, v;
    step = 0;
    s.clear();

    for (int i = 0; i < 52; i++) {
        scanf("%d", &x);
        if (x == 0)
            return false;
        u.push_back(x);
    }

    s.push_back(u);
    for (int i = 0; i < 7; i++)
        s.push_back(v);
    return true;
}

void put (vector<deq> S) {
    for (int i = 0; i < 8; i++) {
        printf("%d:", i);

        while (!S[i].empty()) {
            printf(" %d", S[i].front());
            S[i].pop_front();
        }
        printf("\n");
    }
}

bool get_card (deq& now, int n, int* num) {
    for (int i = 0; i < n; i++) {
        if (now.empty())
            return false;

        num[2-i] = now.back();
        now.pop_back();
    }
    for (int i = 0; i < 3-n; i++) {
        if (now.empty())
            return false;
        num[i] = now.front();
        now.pop_front();
    }
    return true;
}

int solve () {
    set<vector<deq> > g;
    g.insert(s);

    int pos = 0, vis[10], fuck;
    memset(vis, 0, sizeof(vis));

    while (true) {

        if (s[0].empty())
            return 1;

        do {
            pos = (pos + 1) % 7 + 1;
        } while (vis[pos]);

        step++;

        /*
        scanf("%d", &fuck);
        printf("\n");
        put(s);
        */

        int u = s[0].front();
        s[0].pop_front();

        s[pos].push_back(u);

        bool get = true;
        while (get) {
            get = false;

            for (int i = 1; i <= 3; i++) {
                int num[3], sum = 0;
                deq now = s[pos];

                if (get_card(now, i, num) == false)
                    break;

                for (int j = 0; j < 3; j++)
                    sum += num[j];

                if (sum % 10)
                    continue;

                get = true;
                for (int j = 0; j < 3; j++)
                    s[0].push_back(num[j]);
                s[pos] = now;
                break;
            }
        }

        if (s[pos].empty())
            vis[pos] = 1;

        if (judge_end())
            return 2;

        if (g.count(s))
            return 0;
        g.insert(s);
    }
    return 0;
}

int main () {
    while (init()) {
        int flag = solve();
        printf("%s %d\n", sign[flag], step);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值