9.26T5 CQBZ

                                                                                                                                     2 排序 (sorting.cpp/c/pas)

2.1 问题描述

shell排序是众多排序算法中的一种。给定N个互不相同的整数,存放在数组A中,排成升序。Shell排序的 代码段在附加的shell.cpp中。 此处的i, N, X, gap, temp, ok 均是整数。数组A的元素互不相同,取值范围在1 N之间。如果第11行被遗漏 了,这个有bug的shell排序程序在X取某些值时,仍然有可能得到正确的排序结果。 请你找出所有能得到正确排序结果的X。

 1 gap = X;
 2 do
 3 {    ok=1;
 4     for (i = 1; i<= N-gap; i++)
 5         if (A[i] > A[i+gap])
 6         {    temp = A[i];
 7             A[i] = A[i+gap];
 8             A[i+gap] = temp;
 9             ok = 0;
10         }
11     if (gap/2 > 1)  gap=gap/2; else gap=1;
12 }while (ok == 0);

 

2.2 输入格式

从sorting.in读取输入文件。

第1行:1个整数N,表示要排序的元素个数

第2行:N个整数,表示要排序的数组A

2.3输出格式

向sorting.out输出你的答案。

第1行:1个整数C,表示X有多少种不同的取值方案,能得到正确排序结果

第2行:C个整数,表示能得到正确排序结果的X的取值

2.4 样例输入

6

4 2 6 1 5 3

2.5 样例输出

2

1 3

2.6 样例解释

有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).

2.7 数据范围和约定

对于20%的数据,𝑛 ≤ 1000

对于100%的数据,𝑛 ≤ 500000

 

 

其实也是一道水题

因为gap不再改变,所以间隔值是固定的,这就导致只会间隔为gap-1的数之间交换

首先构造一个同样的b数组,排完序之后记录一下与原来的位置差,证明这个数在gap-1间隔之间交换的若干次

所以结论就出来了

对所有数的位置差求一个共同gcd,找gcd的因数就可以了

code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int a[500005],b[500005];
 7 int pos[500005];
 8 int gcd(int a,int b){
 9     if(a<b)swap(a,b);
10     while(a=a%b)swap(a,b);
11     return b;
12 }
13 int g[100005];
14 int main(){
15     int n;cin>>n;
16     for(int i=1;i<=n;i++){
17         cin>>a[i];
18         pos[a[i]]=i;
19         b[i]=a[i];
20     }
21     sort(b+1,b+n+1);
22     int s=0;
23     int last=0;
24     for(int i=1;i<=n;i++){
25         if(i==pos[b[i]])continue;
26         if(!last)last=abs(pos[b[i]]-i);
27         else last=gcd(last,abs(pos[b[i]]-i));
28     }
29     for(int i=1;i*i<=last;i++){
30         if(last%i==0){
31             g[++s]=i;
32         }
33         if(last/i!=i)g[++s]=last/i;
34     }
35     cout<<s<<endl;
36     for(int i=1;i<=s;i++)cout<<g[i]<<" ";
37     return 0;
38 } 

over

posted @ 2018-09-26 20:15  saionjisekai  阅读(41)  评论(0编辑  收藏  举报