PAT乙级1035

来源:互联网 发布:php软件工程师 编辑:程序博客网 时间:2024/06/06 01:53

1035. 插入与归并(25)

时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成N个只包含1个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下1个有序的序列。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

输入格式:

输入在第一行给出正整数N (<=100);随后一行给出原始序列的N个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。

输出格式:

首先在第1行中输出“Insertion Sort”表示插入排序、或“Merge Sort”表示归并排序;然后在第2行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行末不得有多余空格。

输入样例1:
103 1 2 8 7 5 9 4 6 01 2 3 7 8 5 9 4 6 0
输出样例1:
Insertion Sort1 2 3 5 7 8 9 4 6 0
输入样例2:
103 1 2 8 7 5 9 4 0 61 3 2 8 5 7 4 9 0 6
输出样例2:
Merge Sort1 2 3 8 4 5 7 9 0 6

#include<iostream>#include<vector>#include<algorithm>using namespace std;int main(){int N; vector<int> v1,v2;int n;cin >> N;for (int i = 0; i < N; i++){cin >> n;v1.push_back(n);}for (int i = 0; i < N; i++){cin >> n;v2.push_back(n);}bool flag = false;int step = 0;for (int i = 0; i < N-1; i++){if (v2[i] <= v2[i + 1])continue;else{for (int j = i + 1; j < N; j++){step = i+1;if (v2[j] != v1[j]){flag = true;break;//由于测试结果唯一,也就说不是插排就是归并,那么根据插排的规则,可知前几个必定有序  //后几个必定与未排序的原始序列后面部分相同}}break;}}if (flag){bool flag1 = false;cout << "Merge Sort" << endl;int len = v2.size();int i;//这个地方要注意,在step位置发现不保持有序了,并不代表step就是当前归并长度//举个例子,1 2 3 4 7 8 5 6 0 9,这个序列是归并长度为2时的序列,但step会指到5//因为8>5,不保持有序了,step = 6并不是2,那么对于归并的解决,我的做法是从归并长度//为2开始往后对原始序列v1进行归并排序,每次归并后与当前的归并排序的序列v2的元素作比较//若不等,归并长度翻倍继续进行归并,一直到两个序列完全相等,那么归并长度就能确定下来了。for (i = 2; i <=step; i *= 2){if(!flag1)for (int j = 0; j < len; j += i){sort(v1.begin() + j, v1.begin() + min( i + j, len));}int k;for (k = 0; k < N; k++){if (v1[k] == v2[k])continue;else{break;}}if (k == N){flag1 = true;break;}}if(flag1)step = 2*i;for (int i = 0; i < len; i+=step){sort(v2.begin()+i, v2.begin() + min(step+i, len));}for (int i = 0; i < N; i++){cout << v2[i];if (i != N - 1)cout << " ";elsecout << endl;}}else{cout << "Insertion Sort" << endl;for (int i = step-1; i >= 0; i--){if (v2[step] >= v2[i]){int temp = v2[step];for (int j =step; j >i+1; j--){v2[j] = v2[j-1];}v2[i+1] = temp;break;}if (v2[step] < v2[0])//对于插排,注意当前元素小于之前所有元素的情况就行{int temp = v2[step];for (int j = step; j > 0; j--){v2[j] = v2[j - 1];}v2[0] = temp;break;}}for (int i = 0; i < N; i++){cout << v2[i];if (i != N - 1)cout << " ";elsecout << endl;}}return 0;}

0 0
原创粉丝点击