1035 插入与归并 (25 分)
算法分析
首先把数据进行读入,然后判断其是否为插入排序,如果插排过程中发现的确如此,就输出结果,终止程序。如果插排结束后程序还没有终止,那么即为归并排序,然后利用自下而上的归并排序(详见这一篇博客:“自下而上与自上而下的归并排序”),同样是在寻找到答案后输出结果,并终止程序。
测试点分析
我卡在第二个测试点上,后来发现问题是在这样的数据上面
输入
3
132
132
正确输出
Insertion sort
1 2 3
应该判断为是插排,一开始我的代码判断为归并,我修改之后发现就通过了
希望能对大家有所帮助!
代码实现(有注释)
没有过度压行,思路采用的也是最朴素的方式,如果以后有机会再修改吧
#include<bits/stdc++.h>
using namespace std;
#define N 110
int a[N], b[N];//a,b为读入时的数组
int c[N];//c为a的备份数组(用于插排结束仍未找到结果时恢复原数组a)
int n;
int ans;//用来记录当前的judge结果
bool judge();//判断当前排序结果是否与期望结果相同
void input();//输入数据
void print();//输出下一步排序结果
void Insertion_sort();//插排
void Merge_sort();//归并
int main(){
input();
Insertion_sort();
Merge_sort();
return 0;
}
void input(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%d", a + i);
c[i] = a[i];//备份
}
for(int i = 1; i <= n; ++ i) scanf("%d", b + i);
}
bool judge(){
int t = 1;
for(int i = 1; i <= n; ++ i)
if(a[i] != b[i]) t = 0;
return t;
}
void print(){
for(int i = 1; i <= n; ++ i){
printf("%d", a[i]);
if(i != n) printf(" ");
else printf("\n");
}
return ;
}
void Insertion_sort(){
ans = judge();
for(int i = 1; i <= n; ++ i){
int m = i;
for(int j = 1; j <= i - 1; ++ j)
if(a[j] > a[i]){
m = j;
break;
}
if(m != i){
int M = a[i];
for(int q = i; q >= m + 1; -- q)
a[q] = a[q - 1];
a[m] = M;
if(ans){
puts("Insertion Sort");
print();
exit(0);
}
ans = judge();
}
}
}
void Merge_sort(){
for(int i = 1; i <= n; ++ i)
a[i] = c[i];//恢复原始状态
ans = 0;//恢复原始状态
int t = 2;//最小分割单元
while(1){
for(int i = 1; i <= n; i += t){
sort(a + i, a + min(i + t, n + 1));//注意sort的使用
}
if(ans){
puts("Merge Sort");
print();
exit(0);
}
ans = judge();
t *= 2;
}
return ;
}