湖南大学CCF实训2-6:飞行棋(map模拟)

文章描述了一个简化版的飞行棋游戏,棋盘上有特殊格子可使玩家跳跃,两名玩家轮流掷骰子移动。游戏的目标是首先到达终点。给定骰子掷点的递推公式和游戏规则,需要编写程序判断每局游戏的胜者。输入包括棋盘配置和参数,输出是获胜玩家的名字。示例展示了如何使用映射和循环来模拟游戏过程并决定胜利者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题描述】

       大家当年一定都下过飞行棋吧。现在Lele和Yueyue要下的棋和这个很相似,只是更简单一点而已。

       棋盘由N个格子组成,分别标记为第0格到第N-1格。格子分为两种,一种是普通格子,即表示在该格可以停留。否则是特殊的格子,一旦走到上面,就要根据上面标记的数飞到相应的格子上。如果飞到一个特殊的格子上,则可以继续飞。

       除了第0格外,其他格子都只能容纳一个玩家。即一旦A玩家已经在某个格子上,B玩家又走到这里,A玩家则会被踢回第0格,而B玩家留在这个格子上面。

       第N-1个格子是终点,一旦一个玩家走到这个格子上,该玩家获胜,游戏结束。

       刚刚开始时,两个玩家都站在第0格上,依次扔骰子,根据骰子显示的点数走相应的格子数。比如,玩家在第0格,扔出了5点,则会走到第5个格子上。如果玩家走得超出了棋盘的范围,则要往回走一定的步数。比如,棋盘一共有7(0~6)个格子,玩家在第4格上,扔出了6点,最终他会走到第2格上(4->5->6->5->4->3->2)。

       根据观察,骰子扔出来的数也是有规律的。
       对于每一盘棋,扔出的第一个点数为 F0=(A*C+B)%6+1,第二个点数为 F1=(A*F0+B)%6+1,第三个点数为 F2=(A*F1+B)%6+1 ....依此类推。

       每一盘棋都是由Lele先走,现在就请你当裁判,看谁能获胜。

【输入形式】

      本题目包含多组测试,请处理到文件结束。
      每组数据占两行。
      第一行有4个整数N,A,B,C(含义见题目描述,6<N<200,0<=A,B,C<=2^31)。
      第二行有N个字符串,分别表示棋盘上第0个到第N-1个格子的内容。两个字符串之间用一个空格分隔开。

      如果字符串为"N",则表示这个格子为普通格子。否则字符串为"GX"(X为0到N-1之间的整数)的形式,其中X表示玩家走到这个格子时,要马上飞到第X个格子。
      数据保证第0个和第N-1个格子一定为"N"。

【输出形式】

      对于每组数据,在一行内输出结果。
      如果Lele能赢这盘棋,则输出"Lele",如果Yueyue赢的话,就输出"Yueyue"。

【样例输入】

7 1 0 6
N G3 N N N N N
7 1 0 6
N G4 N N N N N

【样例输出】

Lele
Yueyue

【样例说明】

测试用例保证能有确定结果。

用map方便对名字直接进行索引,大大减少代码量。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,A,B,C;
int fly[202];
map<string,int> mp;
int main()
{
	//注意!!!!!
	//对于无限输入的一定要在while里面进行cin
	//while(ture) cin>>n>>A>>B>>C 是会运行时间过长的  
	while(cin>>n>>A>>B>>C){
		memset(fly,-1,sizeof(fly));
		for(int i=0;i<n;i++){
			char c;
			cin>>c;
			if(c=='G'){
				int num;
				cin>>num;
				fly[i]=num;//从i飞到num 
			}
			if(cin.get()=='\n') break;
		}
		
		mp.clear();
		mp.insert({"Lele",0});
		mp.insert({"Yueyue",0});
		int last=C;
		string now="Lele";
		while(true){
			int step=(A*last+B)%6+1;
			mp[now]+=step;
			if(fly[mp[now]]!=-1) mp[now]=fly[mp[now]];
			//超出范围:
			if(mp[now]>n-1) mp[now]=2*n-2-mp[now];
			//踩在同一个格子:
			if(mp["Lele"]==mp["Yueyue"]){
				if(now=="Lele") mp["Yueyue"]=0;
				else mp["Lele"]=0;
			} 
			//cout<<mp["Lele"]<<" || "<<mp["Yueyue"]<<endl;
			if(now=="Lele") now="Yueyue";
			else now="Lele";
			last=step;
			if(mp["Lele"]==n-1){
				cout<<"Lele"<<endl;
				break;
			}
			if(mp["Yueyue"]==n-1){
				cout<<"Yueyue"<<endl;
				break;
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awars_zpp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值