题目 A1089 Insert or Merge
-
题意
输入一个序列和经过操作之后的一个序列,判断操作是插入排序还是归并排序,然后输出接下来再一次操作后的序列。 -
思路
核心就是需要写出插入排序和归并排序的模拟code,插入排序的一个特点就是排过序的部分是有序的,然后操作是拿出一个数之后找到它要在已排过序部分插入的位置,因为是数组需要挪动而且是递增排序所以直接从后向前扫描,在扫描过程可以挪动。归并排序这里就是采用sort
直接进行排序,只要划分好step
的大小即可。其他的函数模块还包括判断两个序列是否相同和输出最后的结果。 -
Code in C++
#include <cstdio>
#include <algorithm>
const int N = 101;
int origin[N], tempOri[N], middle[N];
int n;
bool isSame(int A[], int B[])
{
for (int i = 0; i < n; ++i)
{
if (A[i] != B[i]) return false;
}
return true;
}
bool showArray(int A[])
{
for (int i = 0; i < n; ++i)
{
printf("%d", A[i]);
if (i < n-1) printf(" ");
}
printf("\n");
}
bool insertSort()
{
bool flag = false;
for (int i = 1; i < n; ++i)
{
if (i != 1 && isSame(tempOri, middle))
{
flag = true;
}
// 进行下一次排序
int tmp = tempOri[i], j = i;
// 从后往前找tmp放置的位置
while (j > 0 && tempOri[j-1] > tmp)
{
tempOri[j] = tempOri[j-1];
--j;
}
tempOri[j] = tmp;
if (flag == true)
{
return true;
}
}
return false;
}
void mergeSort()
{
bool flag = false;
for (int step = 2; step <= n; step *= 2)
{
if (step != 2 && isSame(tempOri, middle))
{
flag = true;
}
// 进行下一次归并排序
for (int i = 0; i < n; i += step)
{
std::sort(tempOri + i, tempOri + std::min(i+step,n));
}
if ( flag == true)
{
showArray(tempOri);
return;
}
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d", &origin[i]);
tempOri[i] = origin[i];
}
for (int i = 0; i < n; ++i)
scanf("%d", &middle[i]);
if (insertSort())
{
printf("Insertion Sort\n");
showArray(tempOri);
}
else
{
printf("Merge Sort\n");
// 恢复
for (int i = 0; i < n; ++i)
tempOri[i] = origin[i];
mergeSort();
}
return 0;
}
小结
想法实现为code的能力还是有点弱,也可以说有点情绪在实现里面吧。
这题主要就是插入排序和归并排序模拟过程的实现。