好长时间没有一次性通过所有测试点了,今天感觉像中奖了一样,蛮开心的,首先是排序算法忘得一干二净,没有一次性完成这个题目的热情之后,一直卡在这个题上面,今天竟然一次性完成了!话不多说,上题。
1035. 插入与归并(25)
时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成N个只包含1个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下1个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数N (<=100);随后一行给出原始序列的N个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第1行中输出“Insertion Sort”表示插入排序、或“Merge Sort”表示归并排序;然后在第2行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行末不得有多余空格。输入样例1:
10 3 1 2 8 7 5 9 4 6 0 1 2 3 7 8 5 9 4 6 0输出样例1:
Insertion Sort 1 2 3 5 7 8 9 4 6 0输入样例2:
10 3 1 2 8 7 5 9 4 0 6 1 3 2 8 5 7 4 9 0 6输出样例2:
Merge Sort 1 2 3 8 4 5 7 9 0 6
对于这个题目,首先需要写两个排序算法,整体思路就是先按照一种排序算法进行判断,如果满足和其中一个算法的中间序列重合,那么在进行一次迭代,输出迭代后的结果,插入排序比较简单,直接按照原始的算法来就行了,然而归并排序通常采用的做法是递归,这样的话,并不能得到中间序列,因为按照递归的做法,应该是一半一半的归并,所以我们要采用的是没2的次方次排序,即第一次归并两个,第二次在第一次的基础上归并四个,依次类推,但是这样的做法可能的复杂度上回高一些。另外就是迭代循环过程中设置flag变量跳出循环,因为每次迭代之后需要判断给定序列是否为当前排序算法的中间序列。
<span style="font-family:Microsoft YaHei;">#include<iostream> #include<vector> using namespace std; int checkVec(vector<int> &a,vector<int> &b, int iSize) { for (int i = 0; i != iSize; ++i) { if (a.at(i)!= b.at(i)) return 0; } return 1; } int InsertSort(vector<int> &a, vector<int> &b, int iSize) { vector<int> c; int flag = 0; for (int i = 1; i != iSize ; ++i) { for (int j = i; j != 0; --j) { if (a.at(j) < a.at(j-1)) { int tmp = a.at(j-1); a.at(j - 1) = a.at(j); a.at(j ) = tmp; } } if (flag) return 1; flag = checkVec(a, b, iSize); } return 0; } int Merge(vector<int> &a, int startIndex, int midIndex, int endIndex) { vector<int> c; int i = startIndex, j = midIndex+1; int k = 0; while (i != midIndex+1 && j != endIndex+1) { if (a.at(i) > a.at(j) ) c.push_back(a.at(j++)); else c.push_back (a.at(i++)); } while (i != midIndex + 1) c.push_back(a.at(i++)); while (j != endIndex + 1) c.push_back(a.at(j++)); i = startIndex; k = 0; while (i != endIndex+1) { a.at(i++) = c.at(k++); } return 0; } int MergeSort2(vector<int> &a, vector<int>&b) { int startIndex = 0; int midIndex = 0; int endIndex = 0; int flag = 0; for (int i = 2; i <= a.size()*2; i=i*2) { for (int j = 0; j < a.size(); j = j + i) { startIndex = j; midIndex = j + i / 2 - 1; endIndex = j + i - 1; if (j + i - 1> a.size()) { endIndex = a.size() - 1; if (midIndex >= endIndex) midIndex = endIndex - 1; } Merge(a, startIndex, midIndex, endIndex); } if (flag) return 1; flag = checkVec(a, b, a.size()); } return 0; } int main() { int iSize; cin >> iSize; vector<int> a; vector<int> b; int tmp; //输入原始序列 for (int i = 0; i != iSize; ++i) { cin >> tmp; a.push_back(tmp); } vector<int> a2(a); for (int i = 0; i != iSize; ++i) { cin >> tmp; b.push_back(tmp); } if (MergeSort2(a, b)) { cout << "Merge Sort" << endl; for (int i = 0; i != a.size()-1; ++i) cout << a.at(i) << " "; cout << a.at(a.size() - 1) << endl; } else { InsertSort(a2, b, iSize); cout << "Insertion Sort" << endl; for (int i = 0; i != a2.size() - 1; ++i) cout << a2.at(i) << " "; cout << a2.at(a2.size() - 1) << endl; } return 0; }</span>