【SWTR-01】Sweet Round 01 T1 Escape
官方题解
结论水题,部分分留给你们瞎打的(逃
结论:设所有的可行步数为
-
如果
gcd(b_1,b_2,\dots,b_x,n)=1 ,则答案为n -
否则不可行,输出
-1
注意到
如果
看看你有没有特判下面这组数据
input
1
1 1
1
output
-1
解析:
设
- 如果
d>1 ,易知不可能完成,即只能跳到编号为d 的倍数的平台
易知 “如果有一个
现在需要证明 "如果
(注:以下为这道题目结论的证明,并不是的真正实现方法)
设
如果
否则只能跳到 编号是
接下来是很重要的一点!
- 如果我们能跳到
mod\ d_1=1 的任意一个平台,mod\ d_1=2 的任意一个平台,\dots ,mod\ d_1=d_1-1 的任意一个平台,那么我们就能跳到所有平台
因为如果你跳到了任意一个
例如
跳
跳
跳
跳
跳
这样,问题就从原来的
被简化成了
又因为
有了结论,代码可好打了:
/*
DO NOT CHEAT!
author : Alex_Wei
time : 2019.9.13
language : C++
*/
#include<bits/stdc++.h>
using namespace std;
/*
快读
inline void read(int &x)
{
x=0;char s=getchar();
while(!isdigit(s))s=getchar();
while(isdigit(s))x=(x<<1)+(x<<3)+s-'0',s=getchar();
}
*/
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;}//特判 n=k=1 的情况
for(int i=1;i<=n;i++)
if(!pd[i])//如果可以走,求 gcd
d=gcd(d,i);
if(d>1)cout<<"-1\n";//d>1
else cout<<n<<endl;
for(int i=1;i<=k;i++)
pd[a[i]]=0;//取消标记,不然 memset (可能会)超时
}
return 0;
}