打卡信奥刷题(3042)用C++实现信奥题 P6560 [SBCOI2020] 时光的流逝

P6560 [SBCOI2020] 时光的流逝

题目背景

时间一分一秒的过着,伴随着雪一同消融在了这个冬天,
或许,要是时光能停留在这一刻,该有多好啊。

“这是…我在这个小镇的最后一个冬天了吧。”
“嗯,你可不能这辈子都呆在这个小镇吧。外面的世界很大呢,很大很大…”
“唔…外面的世界…突然有点期待呢!”
“总有一天,你会走得很远很远。以后你可不要忘记这个小镇那。”
“不会的,至少…这里曾经是我最快乐的一段回忆呢!你也一定不要忘记我呀。”
“你看,这雪花。传说,每当世界上有一份思念,便会化成一片雪花在这里飘落。”
“那…以后你可一定要找到我的那片雪花啊…”

“嗯,不如我们一起在这个冬天创造最后一段回忆吧。”
“好呀,我们玩个游戏吧…”

题目描述

这个游戏是在一个有向图(不保证无环)上进行的。每轮游戏开始前,她们先在图上选定一个起点和一个终点,并在起点处放上一枚棋子。

然后两人轮流移动棋子,每次可以将棋子按照有向图的方向移动至相邻的点。

如果谁先将棋子移动至终点,那么谁就胜利了。同样,如果谁无法移动了,那么谁就失败了。

两人轮流操作,请问,他们是否有必胜策略呢?

答案为一个整数 01-1,其中 1 表示(先手)有必胜策略,-1 表示后手有必胜策略,0 表示两人均无必胜策略。

输入格式

1\text{1}1行有三个整数 n,m,qn,m,qn,m,q ,表示图上有 nnn 个点, mmm 条边,一共进行 qqq 轮游戏。
接下来 mmm 行,每行输入两个数 ui,viu_i,v_iui,vi ,表示 uiu_iuiviv_ivi 有一条边。
接下来 qqq 行,每行两个数 x,yx,yx,y ,表示每轮操作的起点和终点。数据保证起点,终点不同

输出格式

对于每轮游戏,仅输出一个整数 01-1,其中 1 表示先手有必胜策略,-1 表示后手有必胜策略,0 表示两人均无必胜策略。

输入输出样例 #1

输入 #1

7 7 1
1 2
2 3
3 4
4 5
3 6
7 5
6 7
1 5

输出 #1

1

输入输出样例 #2

输入 #2

5 5 2
1 2
2 3
3 1
3 4
4 5
1 5
4 3

输出 #2

0
1

说明/提示

样例解释 KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲1

为描述题意,假设两人为 A(先手)和 B

如图,A 先走,走到 222,B 走到 333,接下去 A 可以选择走到 444666,若走到 444,接下去 B 可以走到终点,故不可取。若选择走到 666,那么 B 只能走到 777,A 可以走到终点。所以 A 有必胜策略。

样例解释 KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲2

如图,起点为 111,终点为 555 时, A 和 B 会沿着 1−2−3−11-2-3-11231 的顺序轮流走。因为如果谁先走到 444,那么下一个人就可以走到终点。故谁都没有必胜策略。

起点为 444,终点为 333 时,A 先走到 555,B 无路可走,故 B 失败。

数据范围

对于 10%10\%10% 的数据,保证图是一条链。

对于 50%50\%50% 的数据,1≤n≤1031\leq n\leq 10^31n1031≤m≤2×1031\leq m\leq 2\times10^31m2×1031≤q≤101\leq q\leq 101q10

对于 70%70\%70% 的数据,1≤n≤1051\leq n\leq 10^51n1051≤m≤2×1051\leq m\leq 2\times10^51m2×1051≤q≤101\leq q\leq 101q10

对于 100%100\%100% 的数据,1≤n≤1051\leq n\leq 10^51n1051≤m≤5×1051\leq m\leq 5\times10^51m5×1051≤q≤5001\leq q\leq 5001q500

C++实现

#include <bits/stdc++.h>
using namespace std;
int n,m,q,nxt[500005],a,b;
int main()
{
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b;
		nxt[a]=b; //由于是链表
	}
	for(int i=1;i<=q;i++)
	{
		cin>>a>>b;
		int k=-1,x=a,f=0; //x表示当前位置,k表示当前走棋的人
		while(nxt[x])
		{
			k=-k; //每次转换走棋的人
			x=nxt[x]; //走到下一个位置
			if(x==b) //到终点
			{
				cout<<k<<endl;
				f=1;
				break;
			}
		}
		if(!f)
			cout<<k<<endl; //如果走到终点,则无法动的人输
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值