#[Aizu Onlinejudge]ALDS1_6_C QuickSort

本文介绍了一种判断快速排序算法稳定性的方法,并提供了两种实现方案。通过对输入数据进行特殊处理,能够准确判断排序后的结果是否保持了原始输入的顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem

portal:Quick Sort

Description

Let’s arrange a deck of cards. Your task is to sort totally n cards. A card consists of a part of a suit (S, H, C or D) and an number. Write a program which sorts such cards based on the following pseudocode:

Partition(A, p, r)
1 x = A[r]
2 i = p-1
3 for j = p to r-1
4     do if A[j] <= x
5        then i = i+1
6            exchange A[i] and A[j] 
7 exchange A[i+1] and A[r]
8 return i+1


Quicksort(A, p, r)
1 if p < r
2    then q = Partition(A, p, r)
3        run Quicksort(A, p, q-1)
4        run Quicksort(A, q+1, r)

Here, A is an array which represents a deck of cards and comparison operations are performed based on the numbers.
Your program should also report the stability of the output for the given input (instance). Here, ‘stability of the output’ means that: cards with the same value appear in the output in the same order as they do in the input (instance).

Input

The first line contains an integer n, the number of cards.
n cards are given in the following lines. Each card is given in a line and represented by a pair of a character and an integer separated by a single space.

Output

In the first line, print the stability (“Stable” or “Not stable”) of this output.
In the following lines, print the arranged cards in the same manner of that of the input.

Constraints

  • 1 ≤ \leq n ≤ \leq 100,000
  • 1 ≤ \leq the number of a card ≤ \leq 109
  • There are no identical card in the input

Sample

Sample Input 1

6
D 3
H 2
D 1
S 3
D 2
C 1

Sample Output 1

Not stable
D 1
C 1
D 2
H 2
D 3
S 3

Sample Input 2

2
S 1
H 1

Sample Output 2

Stable
S 1
H 1

Solution

First try

Analysis

Pseudo code for the quick sort algorithm has been given. The task now is to determine if the sorting result is stable.
Insert sort is a stable sorting algorithm, so you can judge whether quick sort is stable for this input by comparing the sorting result of quick sorting and insert sorting.

Design

I need to create a structure that stores input data, I call it Card, it has two elements, int type num and char type sign. Then modified the two sorting algorithm to make them suitable for the structure I created.

Code
// 通过使用稳定排序与快速排序进行比较, 从而确定结果的稳定性
#include <iostream>
using namespace std;

struct Card {
	int num;
	char sign;
};
void swap(Card &a, Card &b)
{
	Card temp;
	temp.num = a.num;
	temp.sign = a.sign;
	a.num = b.num;
	a.sign = b.sign;
	b.num = temp.num;
	b.sign = temp.sign;
}
int quickSortDo(Card A[], int p, int r)
{
	Card x;
	x.num = A[r].num;
	x.sign = A[r].sign;
	int i = p - 1;
	for (int j = p; j < r; j++)
		if (A[j].num <= x.num)
			swap(A[j], A[++i]);
	swap(A[r], A[++i]);
	return i;
}
void quickSort(Card A[], int p, int r)
{
	if (p < r)
	{
		int q = quickSortDo(A, p, r);
		quickSort(A, p, q-1);
		quickSort(A, q+1, r);
	}
}
void insertionSort(Card A[], int len)
{
	int i, j;
	Card temp;
	for (i = 1; i < len; i++)
	{
		temp.num = A[i].num;
		temp.sign = A[i].sign;
		for (j = i - 1; A[j].num > temp.num && j != -1; j--)
		{
			A[j+1] = A[j];
			A[j+1].num = A[j].num;
			A[j+1].sign = A[j+1].sign;
		}
		A[j+1].num = temp.num;
		A[j+1].sign = temp.sign;
	}
}

int main(void)
{
	int n, i;
	cin >> n;
	Card cards[n], cardsBackup[n];
	for (i = 0; i < n; i++)
	{
		cin >> cards[i].sign >> cards[i].num;
		cardsBackup[i].sign = cards[i].sign;
		cardsBackup[i].num = cards[i].num;
	}
	quickSort(cards, 0, n-1);
	insertionSort(cardsBackup, n);
	bool flag = true;
	for (i = 0; i < n; i++)
	{
		if (cards[i].num == cardsBackup[i].num && cards[i].sign == cardsBackup[i].sign)
			continue;
		else
		{
			flag = false;
			break;
		}
	}
	if (flag)
		cout << "Stable" << endl;
	else
		cout << "Not stable" << endl;
	for (i = 0; i < n; i++)
		cout << cards[i].sign << " " << cards[i].num << endl;
}
Result

Judge: 8/10
C++
CPU: 01:63 sec
Memory: 4472 KB
Length: 1643 B
2019-03-31 08:55

Case #VerdictCPU TimeMemoryInOutCase Name
Case #1: Accepted00:0030722635testcase_00
Case #2: Accepted00:0030041015testcase_01
Case #3: Accepted00:0031128387testcase_02
Case #4: Accepted00:003096179187testcase_03
Case #5: Accepted00:003016183191testcase_04
Case #6: Accepted00:0030885155testcase_05
Case #7: Accepted00:093344149069149074testcase_06
Case #8: Accepted00:493784374871374876testcase_07
Case #9: Time Limit Exceeded01:634472717543717548testcase_08
Case #10--755583755587testcase_09

I only passed 8 test examples, I need to read other people’s code to learn how to solve this problem skillfully, not just using brute force.

Second try

Analysis

I read the code of other people (portal), knowing that the order of input can be recorded in the structure. After sorting by value, compare the input order of the same value data. If there is an order exception, it can be determined that quick sort is not stable for this input. otherwise, is stable.

Design

Create a structure that has three elements, int type num and order, char type sign. After quick sort, I can compare the order to determine if quick sort is stable for this input.

Code
// 声明: 以下代码是参考 naoto173 的代码做出来的
// 网址: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2091489#1

#include <iostream>
using namespace std;

struct Card
{
	char sign;
	int num;
	int order;
};

int quickSortDo(Card A[], int left, int right)
{
	Card x = A[right];
	int i = left - 1;
	for (int j = left; j < right; j++)
		if (A[j].num <= x.num)
			swap(A[j], A[++i]);
	swap(A[++i], A[right]);
	return i;
}

void quickSort(Card A[], int left, int right)
{
	if (left < right)
	{
		int middle = quickSortDo(A, left, right);
		quickSort(A, left, middle - 1);
		quickSort(A, middle + 1, right);
	}
}

int main(void)
{
	const int MAX = 100000;
	Card cards[MAX];
	int n, i;
	cin >> n;
	for (i = 0; i < n; i++)
	{
		cin >> cards[i].sign >> cards[i].num;
		cards[i].order = i;
	}

	quickSort(cards, 0, n-1);
	bool flag = true;
	for (i = 0; i < n - 1; i++)
	{
		if (cards[i].num == cards[i+1].num && cards[i].order > cards[i+1].order)
		{
			flag = false;
			break;
		}
	}

	if (flag)
		cout << "Stable" << endl;
	else
		cout << "Not stable" << endl;

	for (i = 0; i < n; i++)
		cout << cards[i].sign << " " << cards[i].num << endl;
}
Result

Status
Judge: 10/10
C++
CPU: 00:11 sec
Memory: 4268 KB
Length: 1160 B
2019-03-31 10:25
Results for testcases

Case #VerdictCPU TimeMemoryInOutCase Name
Case #1: Accepted00:0030842635testcase_00
Case #2: Accepted00:0030841015testcase_01
Case #3: Accepted00:0031048387testcase_02
Case #4: Accepted00:003076179187testcase_03
Case #5: Accepted00:003080183191testcase_04
Case #6: Accepted00:0030205155testcase_05
Case #7: Accepted00:013336149069149074testcase_06
Case #8: Accepted00:053592374871374876testcase_07
Case #9: Accepted00:114132717543717548testcase_08
Case #10: Accepted00:114268755583755587testcase_09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值