ALDS1_6_C QuickSort
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 # | Verdict | CPU Time | Memory | In | Out | Case Name |
---|---|---|---|---|---|---|
Case #1 | : Accepted | 00:00 | 3072 | 26 | 35 | testcase_00 |
Case #2 | : Accepted | 00:00 | 3004 | 10 | 15 | testcase_01 |
Case #3 | : Accepted | 00:00 | 3112 | 83 | 87 | testcase_02 |
Case #4 | : Accepted | 00:00 | 3096 | 179 | 187 | testcase_03 |
Case #5 | : Accepted | 00:00 | 3016 | 183 | 191 | testcase_04 |
Case #6 | : Accepted | 00:00 | 3088 | 51 | 55 | testcase_05 |
Case #7 | : Accepted | 00:09 | 3344 | 149069 | 149074 | testcase_06 |
Case #8 | : Accepted | 00:49 | 3784 | 374871 | 374876 | testcase_07 |
Case #9 | : Time Limit Exceeded | 01:63 | 4472 | 717543 | 717548 | testcase_08 |
Case #10 | - | - | 755583 | 755587 | testcase_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 # | Verdict | CPU Time | Memory | In | Out | Case Name |
---|---|---|---|---|---|---|
Case #1 | : Accepted | 00:00 | 3084 | 26 | 35 | testcase_00 |
Case #2 | : Accepted | 00:00 | 3084 | 10 | 15 | testcase_01 |
Case #3 | : Accepted | 00:00 | 3104 | 83 | 87 | testcase_02 |
Case #4 | : Accepted | 00:00 | 3076 | 179 | 187 | testcase_03 |
Case #5 | : Accepted | 00:00 | 3080 | 183 | 191 | testcase_04 |
Case #6 | : Accepted | 00:00 | 3020 | 51 | 55 | testcase_05 |
Case #7 | : Accepted | 00:01 | 3336 | 149069 | 149074 | testcase_06 |
Case #8 | : Accepted | 00:05 | 3592 | 374871 | 374876 | testcase_07 |
Case #9 | : Accepted | 00:11 | 4132 | 717543 | 717548 | testcase_08 |
Case #10 | : Accepted | 00:11 | 4268 | 755583 | 755587 | testcase_09 |