PAT甲级1089. Insert or Merge

PAT甲级1089. Insert or Merge

题意:

根据维基百科:

插入排序迭代,消耗一个输入元素每次重复,并增加排序的输出列表。每次迭代,插入排序从输入数据中删除一个元素,在排序列表中找到它所属的位置,并将其插入到该列表中。它重复,直到没有输入元素保留。
合并排序工作如下:将未排序的列表分为N个子列表,每个子列表包含1个元素(1个元素的列表被视为排序)。然后重复合并两个相邻的子列表以生成新的排序子列表,直到只剩下1个子列表。

现在给出整数的初始序列,
连同一些序列,这是一些排序方法的几次迭代的结果,你能告诉我们使用哪种排序方法吗?

输入规格:

每个输入文件包含一个测试用例。对于每种情况,第一行给出正整数N(<= 100)。然后在下一行中,给出N个整数作为初始序列。
最后一行包含N个数的部分排序顺序。假设目标序列总是上升。一行中的所有数字都以空格分隔。

输出规格:

对于每个测试用例,请在第一行打印“插入排序”或“合并排序”以指示用于获取部分结果的方法。
然后运行此方法再一次迭代,并在第二行输出结果序列。确保每个测试用例的答案是唯一的。一行中的所有数字必须用一个空格分开,并且行尾不能有额外的空格。

思路:

找到第一个逆序的地方,理论上,如果是插入,这个逆序的地方往后都不会有变化。归并反之。
插入很好处理。归并的话要找到此时的interval即可。

ac代码:

C++

// pat1089.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<stdio.h>
#include<map>
#include<cmath>
#include<unordered_map>
#include<unordered_set>

using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	vector<int> list1(n);
	vector<int> list2(n);

	for (int i = 0; i < n; i++)
	{
		scanf("%d", &list1[i]);
	}
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &list2[i]);
	}

	int pos = 0;
	for (int i = 1; i < n; i++)
	{
		if (list2[i] < list2[i - 1])
		{
			pos = i;
			break;
		}
	}
	bool flag = true;
	for (int i = pos; i < n; i++)
	{
		if (list1[i] != list2[i])
		{
			flag = false;
			break;
		}
	}

	if (flag)
	{
		printf("Insertion Sort
");
		sort(list2.begin(), list2.begin() + pos + 1);
		for (int i = 0; i < n - 1; i++)
			printf("%d ", list2[i]);
		printf("%d
", list2[n - 1]);
	}
	else
	{
		printf("Merge Sort
");
		int interval = pos;
		for (int i = pos; i >= 1; i--)
		{
			flag = true;
			for (int j = 0; j * i < n; j++)
			{
				for (int u = i * j + 1; u < i * (j + 1) && u < n; u++)
				{
					if (list2[u] < list2[u - 1])
					{
						flag = false;
						break;
					}
				}
				if (!flag) break;
			}
			if (flag)
			{
				interval = i; 
				break;
			}
		}

		interval *= 2;
		for (int i = 0; i * interval < n; i++)
		{
			if((i + 1) * interval < n)
				sort(list2.begin() + i * interval, list2.begin() + (i + 1) * interval);
			else
				sort(list2.begin() + i * interval, list2.end());
		}

		for (int i = 0; i < n - 1; i++)
			printf("%d ", list2[i]);
		printf("%d
", list2[n - 1]);
	}
    return 0;
}


原文地址:https://www.cnblogs.com/weedboy/p/7323917.html