题目大意
$shell$排序是众多排序算法中的一种。给定$N$个整数,存放在数组$A$中,排成升序。下表是两种不同语言的排序程序代码段:

此处的$i,N,X,gap,temp,ok$均是整数。数组$A$的元素互不相同,取值范围在$1\rightarrow N$之间。如果第$11$行被遗漏了,这个有bug的$shell$排序程序在$X$取某些值时,仍然有可能得到正确的排序结果。
请你找出所有能得到正确排序结果的$X$。
题目分析
顺带学习了一下希尔排序的玄学$gap$的使用姿势。
当$X$不变时,希尔排序只会指定距离为$X$的进行交换,那么若一个数想归位,其所在位置与应在位置之差必须是$X$的倍数。
因此我们统计出所在位置与应在位置之差的最大公约数$gcd$,$gcd$的所有约数即为答案。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } int n,gcd; vector<int>ans; int main() { n=Get_Int(); for(int i=1; i<=n; i++) { int x=Get_Int(); gcd=__gcd(gcd,abs(x-i)); } for(int i=1; i<=sqrt(gcd); i++) if(gcd%i==0) { ans.push_back(i); if(gcd/i!=i)ans.push_back(gcd/i); } sort(ans.begin(),ans.end()); printf("%d\n",ans.size()); for(int& x:ans)printf("%d ",x); return 0; }
|