1059:Chutes and Ladders(飞行棋)(已翻译)

描述

A popular board game for children is called "Chutes and Ladders". The board has squares which are numbered from 1 to 100, and players have counters which start on the theoretical square 0. The players take turns at throwing a die with the numbers 1 to 6 on it, and each moves his or her counter forward the number of squares corresponding to the number on the die (the square they reach is found by adding the die number to the square number their counter is on). The first person to reach square 100 is the winner.
The interest is caused by the fact that pairs of squares are connected together by "ladders" (which connect a lower-numbered square to a higher-numbered square) and "chutes" (which run from high to low). If a counter lands on the start of a chute or ladder (i.e., this is the square reached after throwing the die), then the counter is moved to the corresponding square at the end of the chute or ladder. Note that landing on the end square of a ladder or a chute has no effect, only the start square counts. Furthermore, there are some squares such that if a player's counter lands on them, then the player must either miss the next turn, or immediately throw the die again for another turn, depending on what is written on the board. A miss-a-turn or extra-turn square is never the start or end of a ladder or chute. If a player is on square 95 or higher, then a die throw which takes them past 100 must be ignored - thus a player on square 99 must ignore all throws which are not 1.

一种流行的儿童棋盘游戏叫做“飞行棋”。棋盘上有从1到100的正方形,玩家有从理论正方形0开始的计数器。玩家轮流投掷一个上面有数字1到6的骰子,然后每个人将他或她的计数器向前移动与骰子上的数字相对应的方块数(他们到达的方块数是通过将骰子数加到他们计数器上的方块数来找到的)。第一个到达100号方格的人就是赢家。引起人们兴趣的原因是,一对对正方形是由“梯子”(连接较低数量的正方形和较高数量的正方形)和“斜槽”(从高到低)连接在一起的。如果一个计数器落在滑槽或梯子的起点(也就是说,这是掷骰子后到达的正方形) ,那么计数器就会移动到滑槽或梯子末端相应的正方形上。请注意,降落在梯子或降落伞的末端方块没有任何效果,只有开始方块计数。此外,还有一些正方形,如果玩家的计数器落在上面,那么玩家必须要么错过下一回合,要么立即再次掷骰子进行下一回合,这取决于黑板上写了什么。错过一个转弯或额外的转弯方块从来不是梯子或滑道的起点或终点。如果一个玩家在95号方格或者更高的方格上,那么一个掷骰子使他们超过100必须被忽略-因此在99号方格上的一个玩家必须忽略所有不是1的掷骰子。

输入
Input will start with a set of less than 1000 die throws which you must use for all games, starting each new game with the first player "throwing" the first number in the set, the next player "throwing" the second number, and so on. This set of die throws will simply be a list of random numbers between 1 and 6, separated by single spaces, with not more than 80 characters on each line. It will be terminated by the number 0. After this set of die throws, there will be one or more game sets. Each game set is in three parts. The first part is a line containing a single number giving the number of players in the game. This will be more than 1 and less than 6. Then the board is described, in two parts. The first part lists the ladders and the chutes on the board, each ladder or chute being defined on a single line. Each is given by two numbers, from 1 to 99,separated by one or more spaces. The first number gives the start square, and the second number gives the end square; so it is a ladder if the first number is less than the second number, and a chute if the order is the other way. The chute/ladder definitions are terminated by a line containing two 0's. The second part of the board description gives the lose-a-turn/extra-turn squares, if there are any. These are single numbers, one per line, defining the squares. If the number is negative, its positive counterpart is a lose-a-turn square; if positive, it represents an extra-turn square. (For example, -16 means that square 16 on the board is a lose-a-turn square, while a 25 means that players landing on square 25 must immediately roll again.) The end of this set of descriptions, and of the game description, is given by a single 0. The end of all the game descriptions is given by a game with the number of players equal to 0.

输入将从一组少于1000个掷骰子开始,你必须在所有游戏中使用,每个新游戏开始时,第一个玩家“扔”第一个数字,下一个玩家“扔”第二个数字,以此类推。这组骰子掷出将仅仅是一个介于1和6之间的随机数列表,用单个空格分隔,每行上不超过80个字符。它将以数字0结束。在这套骰子投掷之后,将会有一套或多套游戏。每套游戏分为三个部分。第一部分是一条线,其中包含一个数字,表示游戏中的玩家人数。大于1小于6。然后对板子进行了描述,分为两个部分。第一部分列出了板上的梯子和滑槽,每个梯子或滑槽被定义在一条线上。每个数字由两个数字给出,从1到99,用一个或多个空格分隔。第一个数字给出开始的平方,第二个数字给出结束的平方; 因此,如果第一个数字小于第二个数字,它就是一个梯子; 如果顺序相反,它就是一个斜槽。斜槽/梯子的定义以一条包含两个0的线结束。第二部分的董事会描述给出了失去一个回合/额外的回合正方形,如果有任何。这些是单个数字,每行一个,定义了正方形。如果这个数字是负的,它的正对应物是一个失转方块; 如果是正的,它表示一个额外的转方块。(例如,-16意味着棋盘上的16号方格是一个失回合方格,而25号方格则意味着落在25号方格上的玩家必须立即再次翻滚。)这组描述和游戏描述的结尾由一个0给出。所有游戏描述的结尾由一个玩家数等于0的游戏给出。

输出
Output must be one line for each game in the input, giving the number of the player who wins the game. Every game will determine a winner in fewer throws than those given at the start of the data.

输出必须是输入中的每个游戏的一行,给出赢得游戏的玩家人数。每场比赛将决定一个赢家在更少的投掷比那些在数据的开始。

样例输入
3 6 3 2 5 1 3 4 2 3 1 2 0
2
6 95
99 1
0 0
-3
98
0
2
3 99
6 90
0 0
0
0
样例输出
2
2
来源
Pacific Northwest 1998


分析

本题属于模拟题,虽然通过率不高,但实际上并不难,只要理解了题意模拟游戏场景就能顺利做出来。

题意说的是若干个玩家玩飞行棋,棋盘有101格,分别标0-100,游戏开始时所有玩家都在0格,游戏中玩家轮流掷骰子(1-6点),

若当前格子编号加上骰子掷出的点数小于等于100,则前进骰子掷出的点数个格子,否则不动。前进后有几种情况,若格子是一个“梯子格”,就会从该格前进到指定的更大点数的格子,若格子是一个“滑梯格”,

就会从该格后退到指定的点数小的格子。每个格子还有一个属性,多掷一次骰子或者停一轮,如果最后落到有这两个属性之一的格子里,

则多掷一次骰子,或者下一轮轮空一次。先到达100点的为胜者。

解题用到了vector,set和map结构,vector用于保存输入的点数列表,map结构用于存放“梯子/滑梯对”以及“多掷一次/轮空一次”。

最后的set用于存放模拟时轮空一次的玩家编号。

要注意玩家编号若从0开始,最后输出的时候需要加1。


代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
 
int die[1005],area[105],player[10],sign[10];
int main()
{
	int coun,i,n;
	scanf("%d",&die[1]);
	for(i=2;die[i-1];i++)
	scanf("%d",&die[i]);
	coun=i-1;
	while(scanf("%d",&n)==1&&n)
	{
		for(i=1;i<=100;i++)
			area[i]=i;
		int s,t;
		while(scanf("%d%d",&s,&t)==2&&s&&t)
		area[s]=t;
		while(scanf("%d",&s)==1&&s)
		{
			if(s>0)area[s]=101;
			else area[abs(s)]=-1;
		}
		int dies=0,players=0;
		memset(player,0,sizeof(player));
		memset(sign,0,sizeof(sign));
		while(++dies<coun)
		{
			if(sign[players%n])
				{
					sign[players%n]=0;
					--dies;
				}
			else
			{
				player[players%n]+=die[dies];
				if(player[players%n]>100)player[players%n]-=die[dies];
				else if(player[players%n]==100){printf("%d\n",players%n+1);break;}
 
				else if(player[players%n]!=area[player[players%n]])
				{
					if(area[player[players%n]]==-1)sign[players%n]=1;
					else if(area[player[players%n]]==101)--players;
					else player[players%n]=area[player[players%n]];
				}
			}
			++players;
		}
	}
	return 0; 
}

给个赞和关注吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值