1 条题解
-
0
自动搬运
来自洛谷,原作者为

Alex_Wei
**搬运于
2025-08-24 22:12:12,当前版本为作者最后更新于2019-10-02 19:28:42,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
官方题解
结论水题,部分分留给你们瞎打的(逃
结论:设所有的可行步数为
-
如果 ,则答案为
-
否则不可行,输出
注意到 而不是
如果 ,那么答案肯定是
看看你有没有特判下面这组数据
input 1 1 1 1 output -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; } -
- 1
信息
- ID
- 4555
- 时间
- 1000ms
- 内存
- 25MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者