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,3…n−1,也就是说,你身后的那个平台就是 n − 1 n-1 n−1 号平台。”
“你每次能够顺时针跳 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×i−1 行,两个整数 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 0≤k≤n≤106,1≤n。
保证 ∑ n i ≤ 3 ∗ 10 6 , a j ≤ n \sum{n_i}\leq 3*10^6,a_j\leq n ∑ni≤3∗106,aj≤n,且互不相同。
测试点 1 : 5 % , n = 1 1:5\%,n=1 1:5%,n=1。
测试点 2 : 5 % , n ≤ 5 2:5\%,n\leq5 2:5%,n≤5。
测试点 3 : 10 % , n ≤ 15 3:10\%,n\leq15 3:10%,n≤15。
测试点 4 : 15 % , n ≤ 300 4:15\%,n\leq300 4:15%,n≤300。
测试点 5 : 25 % , n ≤ 5000 5:25\%,n\leq5000 5:25%,n≤5000。
测试点 6 : 40 % , n ≤ 10 6 6:40\%,n\leq10^6 6:40%,n≤106。
梦醒了……
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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容