1035. 插入与归并(25)
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成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的幂次方一组地排序,只要找到这个步长去验证就好了。结果发现由于组与组之间可能还是递增的,所以肯定行不通,就放弃了。
还是只有分别进行插入排序、归并排序,对过程中的每一组进行验证。
代码写得非常不好,但是折腾太久,懒得优化了~开始新的旅程!
using System; using System.Collections.Generic; namespace PAT { class Program { static void Main() { int length = int.Parse(Console.ReadLine()); int[] numbers = GetIntArray(length); int[] sortedNum = GetIntArray(length); int[] temp = new int[length]; numbers.CopyTo(temp, 0); InsertSort(temp, sortedNum, length); MergeSort(numbers, sortedNum, length); } static void InsertSort(int[] numbers,int[] sortedNumbers, int length) { bool flag; for (int i = 1; i < length; i++) { flag = true; int temp = numbers[i]; int j; for (j = i; j > 0 && numbers[j - 1] > temp; j--) numbers[j] = numbers[j - 1]; numbers[j] = temp; for(int k = 0; k < length; k++) { if (numbers[k] != sortedNumbers[k]) flag = false; } if (flag) { i++; temp = numbers[i]; for (j = i; j > 0 && numbers[j - 1] > temp; j--) numbers[j] = numbers[j - 1]; numbers[j] = temp; Console.WriteLine("Insertion Sort"); PrintArray(numbers, length); } } } static void MergeSort(int[] numbers, int[] sortedNumbers, int length) { int step = 0; //进行归并的次数 int temp = 2; do { step++; temp *= 2; } while (length - temp > 0); List<int> MergeArray; List<int> Unit; int[] sortedUnit; int UnitCount; bool flag; for(int i = 1; i <= step; i++) // 需要归并排序的次数 { flag = true; UnitCount = (int)Math.Pow(2, i); sortedUnit = new int[UnitCount]; MergeArray = new List<int>(length); Unit = new List<int>(); Unit.Add(numbers[0]); for(int j = 1; j < length; j++) { if(j % UnitCount == 0) { sortedUnit = Unit.ToArray(); Array.Sort(sortedUnit); MergeArray.AddRange(sortedUnit); Unit = new List<int>(); } Unit.Add(numbers[j]); } sortedUnit = Unit.ToArray(); Array.Sort(sortedUnit); MergeArray.AddRange(sortedUnit); for (int j = 0; j < length; j++) { if (sortedNumbers[j] != MergeArray[j]) flag = false; } if(flag) { i++; UnitCount = (int)Math.Pow(2, i); sortedUnit = new int[UnitCount]; MergeArray = new List<int>(length); Unit = new List<int>(); Unit.Add(numbers[0]); for (int j = 1; j < length; j++) { if ( j % UnitCount == 0) { sortedUnit = Unit.ToArray(); Array.Sort(sortedUnit); MergeArray.AddRange(sortedUnit); Unit = new List<int>(); } Unit.Add(numbers[j]); } sortedUnit = Unit.ToArray(); Array.Sort(sortedUnit); MergeArray.AddRange(sortedUnit); Console.WriteLine("Merge Sort"); PrintArray(MergeArray.ToArray(), length); } } } static void PrintArray(int[] numbers, int length) { for (int k = 0; k < length - 1; k++) Console.Write("{0} ", numbers[k]); Console.Write(numbers[length - 1]); } static int[] GetIntArray(int length) { int[] numbers = new int[length]; string[] numStrs = Console.ReadLine().Split(' '); for (int i = 0; i < length; i++) numbers[i] = int.Parse(numStrs[i]); return numbers; } } }