打卡信奥刷题(1486)用C++实现信奥 P5582 「SWTR-1」Escape

P5582 「SWTR-1」Escape

题目背景

有一天,当 S u n n y \mathrm{Sunny} Sunny 闲逛的时候,发现了一个按钮。

好奇心驱使他按下了这个按钮。

突然间,天旋地转 … \dots

题目描述

醒来之后, S u n n y \mathrm{Sunny} Sunny 发现自己站在一个奇怪的地方。

这个地方有 n n n 个平台,形成了一个环

这时, E t h a n \mathrm{Ethan} Ethan 的声音响起:

“哈哈哈哈哈哈,恭喜你,你是第一个来到死亡之地的人。”

“正如你所看到的,这个地方有 n n n 个平台,你现在站在 0 0 0 号平台上。”

“剩余平台按顺时针编号 1 , 2 , 3 … n − 1 1,2,3\dots n-1 1,2,3n1,也就是说,你身后的那个平台就是 n − 1 n-1 n1 号平台。”

“你每次能够顺时针 i i i 个平台, i ∈ [ 1 , n ] i\in[1,n] i[1,n],每次的 i i i 可以不一样。”

“如果你能够经过所有平台(初始 0 0 0 号位置不算),那你就能逃出死亡之地了。”

(这里指的是一开始的 0 0 0 号位置不算经过,需要再次经过 0 0 0 号位置)

“不过,这样太简单了,我会给你一些数 a j a_j aj,表示你不能一次顺时针跳 a j a_j aj 个平台。”

“还有,你必须要用最少的跳跃次数完成我的任务。”

“如果你不能满足我的上面两个要求,所有平台就会消失,你将会掉入下面的岩浆之中。”

现在, S u n n y \mathrm{Sunny} Sunny 想知道他是否可能逃出这个地方。

如果不行,输出-1,否则输出他最少所需的跳跃次数。

因为 S u n n y \mathrm{Sunny} Sunny 觉得死亡之地实在是太有趣了,所以他决定多玩几次,多组数据

输入格式

第一行,一个正整数 T T T,代表数据组数。

接下来 2 × T 2\times T 2×T 行,共 T T T 组数据:

2 × i − 1 2\times i-1 2×i1 行,两个整数 n , k n,k n,k k k k 代表该组数据 a j a_j aj 的个数。

2 × i 2\times i 2×i 行, k k k 个数,第 j j j 个数表示 a j a_j aj

输出格式

T T T 行,第 i i i 行表示第 i i i 组数据的输出。

输入输出样例 #1

输入 #1

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

输出 #1

-1
5
-1

说明/提示


样例说明

第一组数据:

S u n n y \mathrm{Sunny} Sunny 每次只能顺时针跳 5 5 5 个平台,易知不可能完成。

第二组数据:

S u n n y \mathrm{Sunny} Sunny 每次只能顺时针跳 3 3 3 个平台,跳 5 5 5 次即可。


数据范围与约定

0 ≤ k ≤ n ≤ 10 6 , 1 ≤ n 0\leq k\leq n\leq 10^6,1\leq n 0kn106,1n

保证 ∑ n i ≤ 3 ∗ 10 6 , a j ≤ n \sum{n_i}\leq 3*10^6,a_j\leq n ni3106,ajn,且互不相同

测试点 1 : 5 % , n = 1 1:5\%,n=1 1:5%,n=1

测试点 2 : 5 % , n ≤ 5 2:5\%,n\leq5 2:5%,n5

测试点 3 : 10 % , n ≤ 15 3:10\%,n\leq15 3:10%,n15

测试点 4 : 15 % , n ≤ 300 4:15\%,n\leq300 4:15%,n300

测试点 5 : 25 % , n ≤ 5000 5:25\%,n\leq5000 5:25%,n5000

测试点 6 : 40 % , n ≤ 10 6 6:40\%,n\leq10^6 6:40%,n106


梦醒了……

C++实现

#include<bits/stdc++.h> 
using namespace std;

int t,a[19260817];
bool pd[19260817];
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int main()
{
	scanf("%d",&t);
	for(int l=0;l<t;l++){
		int n,k,d;
		scanf("%d%d",&n,&k),d=n;
		for(int i=1;i<=k;i++)
			scanf("%d",&a[i]),pd[a[i]]=1;
		if(n==1&&k==1)
		{cout<<"-1\n",pd[1]=0;continue;}
		for(int i=1;i<=n;i++)
			if(!pd[i])
				d=gcd(d,i);
		if(d>1)cout<<"-1\n";
		else cout<<n<<endl;
		for(int i=1;i<=k;i++)
			pd[a[i]]=0;
	}
	return 0;
}

在这里插入图片描述

后续

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值