UVA246 - 10-20-30(队列+ 模拟)

题目:UVA246 - 10-20-30(队列+ 模拟)

题目大意:给出52张牌,不分花色,先发七张,形成7堆,然后再从左往右的发牌。如果能够找到三张牌他们的和是10, 20, 30的话,就可以把三张牌按照先后顺序放到你手中的牌的后面。这样一直进行下去,如果你手中有52张牌就赢了,如果你手中没有牌就输了,如果某个状态之前已经出现过,那么就输出draw。然后还要输出总共处理了多少张牌能够得到结果。

解题思路:注意这里不是有三种情况取三张牌,题目貌似保证只会出现这三种中的某一种,这样情况就减少了。然后用队列去模拟,这题学到了一个新的知识点,可以用map来对数组进行判重。

代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <deque>
#include <vector>
#include <map>

using namespace std;

const int N = 7;

int ans;

struct State {

	int v[N * 10];
	bool operator < (const State &a) const {
		return memcmp (v, a.v, sizeof(State)) < 0;
	}
};

queue<int> hand;
deque<int> piles[N];
map<State, int> st;

void handle (deque<int>& pile) {

	while (pile.size() >= 3) {

		int n = pile.size();
		if ((pile[0] + pile[1] + pile[n - 1]) % 10 == 0) {

			hand.push(pile[0]);
			hand.push(pile[1]);
			hand.push(pile[n - 1]);
			pile.pop_front();
			pile.pop_front();
			pile.pop_back();
		} else if ((pile[0] + pile[n - 1] + pile[n - 2]) % 10 == 0) {

			hand.push(pile[0]);
			hand.push(pile[n - 2]);
			hand.push(pile[n - 1]);
			pile.pop_front();
			pile.pop_back();
			pile.pop_back();
		} else if ((pile[n - 1] + pile[n - 2] + pile[n - 3]) % 10 == 0) {

			hand.push(pile[n - 3]);
			hand.push(pile[n - 2]);
			hand.push(pile[n - 1]);
			pile.pop_back();
			pile.pop_back();
			pile.pop_back();
		} else
			return;
	}
}

int solve () {

	for (int k = 0; k < 2; k++) {
		for (int i = 0; i < N; i++) {
			piles[i].push_back(hand.front());
			hand.pop();
		}
	}

	ans = 14;
	State tmp;
	while (hand.size()) {

		for (int i = 0; i < N; i++) {
			if (hand.size() == 52)
				return 1;
			if (piles[i].size() == 0)
				continue;
			if (hand.size()) {

				piles[i].push_back(hand.front());
				hand.pop();
				ans++;
				handle(piles[i]);
                                //判重
				int cnt = 0;
				memset (tmp.v, 0, sizeof (tmp.v));
				for (int k = 0; k < N; k++) {
					for (int j = 0; j < piles[k].size(); j++)
						tmp.v[cnt++] = piles[k][j];
					tmp.v[cnt++] = 11;
				}

				queue<int> q = hand;
				while (!q.empty()) {
					tmp.v[cnt++] = q.front();
					q.pop();
				}
				tmp.v[cnt] = 11;

				if (st[tmp])
					return -1;
				else
					st[tmp] = 1;
			} else
				return 0;
		}
	}
	return 0;
}

void init () {

	while (!hand.empty()) {
		hand.pop();
	}
	st.clear();
	for (int i = 0; i < N; i++)
		piles[i].clear();
}

int main () {

	int card;
	while (scanf ("%d", &card) && card) {

		init();
		hand.push(card);
		for (int i = 0; i < 51; i++) {

			scanf ("%d", &card);
			hand.push(card);
		}

		int tmp = solve();
		if (tmp == 0)
			printf ("Loss: %d\n", ans);
		else if (tmp == 1)
			printf ("Win : %d\n", ans);
		else
			printf ("Draw: %d\n", ans);
	}
	return 0;
}
时间: 2024-09-28 17:48:04

UVA246 - 10-20-30(队列+ 模拟)的相关文章

个人回忆录 2014.10.20 至 2015.7.30

时间过的太快.以至于对我来说都记不起来每天做了些什么事情.工作节奏太快,下班.上班 然后再下班再上班. 每天下班后都晚上9点左右.真的看不见日出看不见日落. 从2014.10.20 到现在已经快10个月了.新的工作环境以及新的同事.上司都已熟悉了.回想刚刚开始进入这个研发团队的时候. 高原反应非常强烈,总是在疑问自己为何选择这个方向—C++ 客户端开发.为何不沿用最熟悉的.NET 平台开发.当从新学习一门新技术的时候 才发现自己太笨.有点像当年的高考,时间很紧.因为没有太多的时间用在学习上.MF

火车车厢重排问题--队列模拟

①问题描述 一列货运列车共有n节车厢,每节车厢将停放在不同的车站.假定n个车站的编号分别为1-n,即货运列车按照第n站至第1站的次序经过这些车站.为了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢.所以,给定任意次序的车厢,必须重新排列它们. 车厢的重排工作可以通过转轨站完成.在转轨站中有一个入轨.一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间.假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题. ②基本要求 设计存储结构表示n个车厢.k

简单数据结构之队列模拟

1 /************************************************************************************** 2 * Function : 模拟队列 3 * Create Date : 2014/04/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

使用两个队列模拟一个栈

准备笔试,在看相关知识,看到这个问题,如何使用两个队列模拟一个栈,在参考了相关知识下,实现了代码如下: 1 public class Stack<E>{ 2 Queue<E> q1 = null; //队列q1提供压栈功能, 3 Queue<E> q2 = null; //队列q2提供弹栈功能 4 5 public Stack(){ 6 q1 = new LinkedList<E>(); 7 q2 = new LinkedList<E>(); 8

数据结构和算法之栈和队列一:两个栈模拟一个队列以及两个队列模拟一个栈

今天我们需要学习的是关于数据结构里面经常看到的两种结构,栈和队列.可以说我们是一直都在使用栈,比如说在前面递归所使用的的系统的栈,以及在链表倒序输出时介绍的自定义栈类Stack和使用系统的栈进行递归.那么,在这里我们就讲述一下这两个比较具有特色的或者说关系比较紧密的数据结构之间的互相实现问题. 一:两个栈模拟实现一个队列: 栈的特点是先进后出,然而队列的特点是先进先出. public class Queen(Stack s1,Stack s2){ //实现插入的方法 public void ad

PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟

假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 有些银行会给VIP客户以各种优惠服务,例如专门开辟VIP窗口.为了最大限度地利用资源,VIP窗口的服务机制定义为:当队列中没有VIP客户时,该窗口为普通顾客服务:当该窗口空闲并且队列中有VIP客户在等待时,排在最前面的VIP客户享受该窗口的服务.同时,当轮到某VIP客户出列时,若VIP窗口非空,该客户可以选择空

双栈模拟队列与双队列模拟栈

1.两个队列共享一个环形向量空间,将这两个队列模拟成栈,并实现十进制转化为二进制 程序如下: 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define maxSize 20 4 typedef int DataType; 5 typedef struct 6 { 7 DataType elem[maxSize]; 8 int front[2],rear[2]; 9 }DualQueue; 10 void InitQueue(DualQue

2-09. 装箱问题模拟(20) (ZJUPAT 模拟)

题目链接:http://pat.zju.edu.cn/contests/ds/2-09 假设有N项物品,大小分别为s1, s2, -, si, -, sN,其中si为满足1<= si<=100的整数.要把这些物品装入到容量为100的一批箱子(序号1-N)中.装箱方法是:对每项物品, 顺序扫描箱子,把该物品放入足以能够容下它的第一个箱子中.请写一个程序模拟这种装箱过程,并输出每个物品所在的箱子序号,以及放置全部物品所需的箱子数目. 输入格式说明: 输入第1行给出物品个数N(<=1000),

用队列模拟基数排序

function Queue() { //用队列模拟基数排序对应的Queue构造函数中的方法一个都不能少,否则会出错 this.dataStore = []; this.enqueue = enqueue; this.dequeue = dequeue; this.empty = empty; } function enqueue(element) {//向队尾添加一个元素 this.dataStore.push(element); } function dequeue() {//删除队首的元素