UVA 246 10-20-30

也是一道模拟的题目,首先是对于7个堆使用双端队列进行模拟,对于手中的牌,使用一个普通队列进行模拟。首先将7个堆中每个堆都放满两张牌,然后依次从手中拿出一张牌,放到每个队列中,放进去之后就进行分析是否能够将牌收回,如果可以就执行收回操作。每次之后就判断手中的牌的数量,如果为52,说明堆中的牌就已经全部收回了,如果为0,说明游戏已经没办法进行,则失败。同时设置一个结构体,存储当前堆中每一张牌的情况以及相应的手中牌的情况,如果不是前面两种成功或者失败的结局,就看看目前所出现的牌局在之前是否出现过,可以利用set来查询,同时注意定义结构体类型的小于操作符,里面的变量以及函数都要申明为const。这个题目还有一个技巧在于,三张牌的和可以为10,20或者30,但三张牌的和的最大值只能为30,所以在后续判断的时候只需要判断是否模10为0即可。具体的实现见下面源代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;

struct status{
	vector<int> data;
	bool operator < (const status& a) const {
		return data < a.data;
	}
};

set<status> record;

void deal(deque<int>& d, queue<int>& deck){
	while (d.size() >= 3){
		int length = d.size();
		if ((d[0] + d[1] + d[length - 1])%10 == 0){
			deck.push(d[0]); deck.push(d[1]); deck.push(d[length - 1]);
			d.pop_front();
			d.pop_front();
			d.pop_back();
		}
		else if ((d[0] + d[length - 2] + d[length - 1])%10 == 0){
			deck.push(d[0]); deck.push(d[length - 2]); deck.push(d[length - 1]);
			d.pop_back();
			d.pop_back();
			d.pop_front();
		}
		else if ((d[length - 3] + d[length - 2] + d[length - 1])%10 == 0){
			deck.push(d[length - 3]); deck.push(d[length - 2]); deck.push(d[length - 1]);
			d.pop_back();
			d.pop_back();
			d.pop_back();
		}
		else{
			break;
		}
	}
}

int main(){
	while (true){
		deque<int> q[7];
		queue<int> deck;
		for (int i = 0; i < 52; i++){
			int t;
			cin >> t;
			if (t == 0) return 0;
			deck.push(t);
		}
		for (int i = 0; i < 7; i++){
			q[i].push_back(deck.front());
			deck.pop();
		}
		for (int i = 0; i < 7; i++){
			q[i].push_back(deck.front());
			deck.pop();
		}
		int cur = 14;
		bool res = false;
		while (!res){
			for (int i = 0; i < 7; i++){
				if (q[i].size() == 0) continue;
				cur++;
				q[i].push_back(deck.front());
				deck.pop();
				deal(q[i], deck);
				if (deck.size() == 52){
					cout << "Win : " << cur << endl;;
					res = true;
					break;
				}
				if (deck.size() == 0){
					cout << "Loss: " << cur << endl;
					res = true;
					break;
				}
				status temp;
				for (int m = 0; m < 7; m++){
					for (int n = 0; n < q[m].size(); n++) temp.data.push_back(q[m][n]);
					temp.data.push_back(-1);
				}
				queue<int> deck2 = deck;
				while (!deck2.empty()){
					int a = deck2.front();
					deck2.pop();
					temp.data.push_back(a);
				}
				if (record.find(temp) != record.end()){
					cout << "Draw: " << cur << endl;
					res = true;
					break;
				}
				record.insert(temp);
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值