1035 插入与归并 (25 分)(测试点二 段错误)

94 阅读2分钟

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 ;
}