想要看随机化的可以看看我的这篇文章
BSOJ4874 -- 【NOIP2016-4】 排序 (noip模拟)
BSOJ4874 -- 【NOIP2016-4】 排序 (noip模拟)
Description
shell 排序是众多排序算法中的一种。给定 N 个整数,存放在数组 A 中,排成升序。下表是两种不同语言的排序程序代码段:
此处的 i, N, X, gap, temp, ok 均是整数。数组 A 的元素互不相同,取值范围在 1~N 之间。如果第 11 行被遗漏了,这个有 bug 的 shell 排序程序在 X 取某些值时,仍然有可能得到正确的排序结果。
请你找出所有能得到正确排序结果的 X。
Input
第1 行:1 个整数 N,表示要排序的元素个数
第2 行:N 个整数,表示要排序的数组 A,保证初始状态非升序。
Output
第1 行:1 个整数 C,表示 X 有多少种不同的取值方案,能得到正确排序结果
第2 行:C 个整数,表示能得到正确排序结果的 X 的取值,升序排列
Sample Input
6
4 2 6 1 5 3
Sample Output
2
1 3
Hint
[样例说明]
有 6 个元素,分别是 4, 2, 6, 1, 5, 3。能得到正确的排序结果的 X 有 2 种取值方案:
•X = 1, 我们交换以下这些位置的元素
(1,2), (3,4), (4,5), (5,6), (2,3), (4,5), (1,2), (3,4);
•X = 3, 我们交换以下这些位置的元素
(1,4), (3,6).
[数据说明]
•1 < N <= 500000
(1,2), (3,4), (4,5), (5,6), (2,3), (4,5), (1,2), (3,4);
•X = 3, 我们交换以下这些位置的元素
(1,4), (3,6).
[数据说明]
•1 < N <= 500000
•1 ≤ X ≤ N-1
先给随机化乱搞。
正解如下,有一个归位的思想即可。
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstdio>
using namespace std;
int n;
int r[500009]={0};
int fir[109]={0};
int sec[109]={0};
bool possible[500009]={0};
void Get_firsec(int x,int i)
{
int yao=0x3fffffff,er=0x3fffffff;
while(x<=n)
{
if(r[x]<yao)
{
er=yao;
yao=r[x];
x+=i;
continue;
}
er=min(er,r[x]);
x+=i;
}
fir[0]++;
fir[fir[0]]=yao;
sec[0]++;
sec[sec[0]]=er;
}
void Solve_belief()
{
srand(time(NULL));
int pos,t;
bool ok;
for(int i=n;i>=1;i--)
{
if(possible[i])continue;
fir[0]=0;
sec[0]=0;
ok=1;
t=min(100,i);
for(int j=0;j<=t-1;j++)
{
pos=(rand()%(i/t))+1;
pos=j*(i/t)+pos;
Get_firsec(pos,i);
if(j>=1)
{
if(fir[j]>fir[j+1]){ok=0;break;}
if(sec[j]>sec[j+1]){ok=0;break;}
}
}
if(ok==0)continue;
possible[i]=1;
for(int j=1;j*j<=i;j++)
{
if(i%j==0)
{
possible[j]=1;
possible[i/j]=1;
}
}
}
int cnt=0;
for(int i=1;i<=n;i++)if(possible[i])cnt++;
cout<<cnt<<endl;
for(int i=1;i<=n;i++)if(possible[i])printf("%d ",i);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&r[i]);
Solve_belief();
fclose(stdout);
return 0;
}
正解如下,有一个归位的思想即可。
#include<iostream>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,cnt=0,h[500005],c1=0;
inline int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int main(){
cin>>n;
int x;
int G=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x!=i)
{
if(!G) G=abs(x-i);
else G=gcd(G,abs(x-i));
}
}
int c1=0;
for(int i=1;i<=G;i++)
if(G%i==0)c1++,h[c1]=i;
sort(h+1,h+c1+1);
cout<<c1<<endl;
for(int i=1;i<=c1;i++)
cout<<h[i]<<" ";
return 0;
}