AOJ/高等排序习题集
ALDS1_5_B-MergeSort.
Description:
Write a program of a Merge Sort algorithm implemented by the following pseudocode. You should also report the number of comparisons in the Merge function.
Merge(A, left, mid, right)
n1 = mid - left;
n2 = right - mid;
create array L[0...n1], R[0...n2]
for i = 0 to n1-1
do L[i] = A[left + i]
for i = 0 to n2-1
do R[i] = A[mid + i]
L[n1] = SENTINEL
R[n2] = SENTINEL
i = 0;
j = 0;
for k = left to right-1
if L[i] <= R[j]
then A[k] = L[i]
i = i + 1
else A[k] = R[j]
j = j + 1
Merge-Sort(A, left, right){
if left+1 < right
then mid = (left + right)/2;
call Merge-Sort(A, left, mid)
call Merge-Sort(A, mid, right)
call Merge(A, left, mid, right)
Input:
In the first line n is given. In the second line, n integers are given.
Output:
In the first line, print the sequence S. Two consequtive elements should be separated by a space character.
In the second line, print the number of comparisons.
Constraints:
n ≤ 500000
0 ≤ an element in S ≤ 109
SampleInput:
10
8 5 9 2 6 3 7 1 10 4
SampleOutput:
1 2 3 4 5 6 7 8 9 10
34
Codes:
//#define LOCAL
#include <cstdio>
#define M 500010
#define SENTINEL 2000000000
int s = 0, A[M], L[M], R[M];
void merge(int l, int m, int r) {
int i, j, k, n1 = m-l, n2 = r-m;
L[n1] = R[n2] = SENTINEL;
for(i=0; i<n1; ++i) L[i] = A[l+i];
for(i=0; i<n2; ++i) R[i] = A[m+i];
i = j = 0;
for(k=l; k<r; ++k) {
if(L[i] <= R[j]) A[k] = L[i++];
else A[k] = R[j++]; ++s;
}
}
void mergeSort(int l, int r) {
if(l+1 < r) {
int m = (l+r)/2;
mergeSort(l, m);
mergeSort(m, r);
merge(l, m, r);
}
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int i, n;
scanf("%d", &n);
for(i=0; i<n; ++i) scanf("%d", &A[i]);
mergeSort(0, n);
for(i=0; i<n; ++i) {
if(i) printf(" ");
printf("%d", A[i]);
}
printf("\n%d\n", s);
return 0;
}
ALDS1_6_B-Partition.
Description:
Quick sort is based on the Divide-and-conquer approach. In QuickSort(A, p, r), first, a procedure Partition(A, p, r) divides an array A[p..r] into two subarrays A[p..q-1] and A[q+1..r] such that each element of A[p..q-1] is less than or equal to A[q], which is, inturn, less than or equal to each element of A[q+1..r]. It also computes the index q.
In the conquer processes, the two subarrays A[p..q-1] and A[q+1..r] are sorted by recursive calls of QuickSort(A, p, q-1) and QuickSort(A, q+1, r).
Your task is to read a sequence A and perform the Partition 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
Input:
The first line of the input includes an integer n, the number of elements in the sequence A.
In the second line, n elements of the sequence are given separated by space characters.
Output:
Print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character. The element which is selected as the pivot of the partition should be indicated by [ ].
Constraints:
1 ≤ n ≤ 100,000
SampleInput:
12
13 19 9 5 12 8 7 4 21 2 6 11
SampleOutput:
9 5 8 7 4 2 6 [11] 21 13 19 12
Codes:
//#define LOCAL
#include <cstdio>
#define M 100010
int A[M];
int partition(int p, int r) {
int i = p-1, a = A[r], j, t;
for(j=p; j<r; ++j) {
if(A[j] <= a) {
++i;
t = A[i]; A[i] = A[j]; A[j] = t;
}
}
A[r] = A[i+1]; A[i+1] = a;
return i+1;
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int i, n, q;
scanf("%d", &n);
for(i=0; i<n; ++i) scanf("%d", &A[i]);
q = partition(0, n-1);
for(i=0; i<n; ++i) {
if(i) printf(" ");
if(i == q) printf("[%d]", A[i]);
else printf("%d", A[i]);
}
printf("\n");
return 0;
}
ALDS1_6_C-QuickSort.
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 ≤ n ≤ 100,000
1 ≤ the number of a card ≤ 109
There are no identical card in the input
SampleInput1:
6
D 3
H 2
D 1
S 3
D 2
C 1
SampleOutput1:
Not stable
D 1
C 1
D 2
H 2
D 3
S 3
SampleInput2:
2
S 1
H 1
SampleOutput2:
Stable
S 1
H 1
Codes:
//#define LOCAL
#include <cstdio>
#define M 100010
#define S 2000000000
struct Card {
char p;
int q;
};
Card A[M], B[M], L[M], R[M];
void merge(int l, int m, int r) {
int i, j, k, n1 = m-l, n2 = r-m;
for(i=0; i<n1; ++i) L[i] = A[l+i];
for(i=0; i<n2; ++i) R[i] = A[m+i];
i = j = 0, L[n1].q = R[n2].q = S;
for(k=l; k<r; ++k) {
if(L[i].q <= R[j].q) A[k] = L[i++];
else A[k] = R[j++];
}
}
void mergeSort(int l, int r) {
if(l+1 < r) {
int m = (l+r)/2;
mergeSort(l, m);
mergeSort(m, r);
merge(l, m, r);
}
}
int partition(int l, int r) {
int i = l-1, j, x = B[r].q;
for(j=l; j<r; ++j) {
if(B[j].q <= x) {
++i;
Card t = B[j]; B[j] = B[i]; B[i] = t;
}
}
Card t = B[r]; B[r] = B[i+1]; B[i+1] = t;
return i+1;
}
void quickSort(int l, int r) {
int m;
if(l < r) {
m = partition(l, r);
quickSort(l, m-1);
quickSort(m+1, r);
}
}
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int i, m, n;
char t[10];
scanf("%d", &n);
for(i=0; i<n; ++i) {
scanf("%s%d", t, &m);
A[i].p = B[i].p = t[0];
A[i].q = B[i].q = m;
}
mergeSort(0, n);
quickSort(0, n-1);
for(i=0; i<n; ++i) {
if(A[i].p != B[i].p) {
printf("Not stable\n");
break;
}
}
if(i == n) printf("Stable\n");
for(i=0; i<n; ++i) {
printf("%c %d\n", B[i].p, B[i].q);
}
return 0;
}
ALDS1_6_A-CountingSort.
Description:
Counting sort can be used for sorting elements in an array which each of the n input elements is an integer in the range 0 to k. The idea of counting sort is to determine, for each input element x, the number of elements less than x as C[x]. This information can be used to place element x directly into its position in the output array B. This scheme must be modified to handle the situation in which several elements have the same value. Please see the following pseudocode for the detail:
Counting-Sort(A, B, k)
1 for i = 0 to k
2 do C[i] = 0
3 for j = 1 to length[A]
4 do C[A[j]] = C[A[j]]+1
5 /* C[i] now contains the number of elements equal to i /
6 for i = 1 to k
7 do C[i] = C[i] + C[i-1]
8 / C[i] now contains the number of elements less than or equal to i */
9 for j = length[A] downto 1
10 do B[C[A[j]]] = A[j]
11 C[A[j]] = C[A[j]]-1
Write a program which sorts elements of given array ascending order based on the counting sort.
Input:
The first line of the input includes an integer n, the number of elements in the sequence.
In the second line, n elements of the sequence are given separated by spaces characters.
Output:
Print the sorted sequence. Two contiguous elements of the sequence should be separated by a space character.
Constraints:
1 ≤ n ≤ 2,000,000
0 ≤ A[i] ≤ 10,000
SampleInput:
7
2 5 1 3 2 3 0
SampleOutput:
0 1 2 2 3 3 5
Codes:
//#define LOCAL
#include <cstdio>
#define M 10010
#define VM 2000010
int A[VM], B[M], C[VM];
int main()
{
#ifdef LOCAL
freopen("E:\\Temp\\input.txt", "r", stdin);
freopen("E:\\Temp\\output.txt", "w", stdout);
#endif
int i, n;
scanf("%d", &n);
for(i=1; i<=n; ++i) {
scanf("%d", &A[i]);
++B[A[i]];
}
for(i=1; i<M; ++i) B[i] += B[i-1];
for(i=n; i>=1; --i) C[B[A[i]]--] = A[i];
for(i=1; i<=n; ++i) {
if(i > 1) printf(" ");
printf("%d", C[i]);
}
printf("\n");
return 0;
}
ALDS1_5_D-TheNumberOfInversions.
Codes:
#include <iostream>
using namespace std;
#define MAX 200000
#define SENTINEL 2000000000
typedef long long llong;
int L[MAX/2+2], R[MAX/2+2];
llong merge(int A[], int n, int left, int mid, int right) {
llong cnt = 0;
int i, j, k, n1 = mid-left, n2 = right-mid;
for(i=0; i<n1; ++i) L[i] = A[left+i];
for(i=0; i<n2; ++i) R[i] = A[mid+i];
i = j = 0, L[n1] = R[n2] = SENTINEL;
for(k=left; k<right; ++k) {
if(L[i] <= R[j]) A[k] = L[i++];
else A[k] = R[j++];
cnt += n1-i;
}
return cnt;
}
llong mergeSort(int A[], int n, int left, int right) {
int mid;
llong v1, v2, v3;
if(left+1 < right) {
mid = (left+right)/2;
v1 = mergeSort(A, n, left, mid);
v2 = mergeSort(A, n, mid, right);
v3 = merge(A, n, left, mid, right);
return v1+v2+v3;
} else return 0;
}
int main()
{
int n, i, A[MAX];
cin >> n;
for(i=0; i<n; ++i) cin >> A[i];
int ans = mergeSort(A, n, 0, n);
cout << ans << endl;
return 0;
}
ALDS1_6_D-MinimumCostSort.
Codes:
#include <iostream>
#include <algorithm>
using namespace std;
static const int MAX = 1000;
static const int VMAX = 10000;
int n, s, A[MAX], B[MAX], T[VMAX+1];
int solve() {
int i, ans = 0;
bool V[MAX];
for(i=0; i<n; ++i) {B[i] = A[i]; V[i] = false;}
sort(B, B+n);
for(i=0; i<n; ++i) T[B[i]] = i;
for(i=0; i<n; ++i) {
if(V[i]) continue;
int S = 0, an = 0, cur = i, m = VMAX;
while(1) {
V[cur] = true; ++an;
int v = A[cur]; m = min(m, v);
S += v; cur = T[v];
if(V[cur]) break;
}
ans += min(S+(an-2)*m, m+S+(an+1)*s);
}
return ans;
}
int main()
{
cin >> n;
s = VMAX;
for(int i=0; i<n; ++i) {
cin >> A[i];
s = min(s, A[i]);
}
int ans = solve();
cout << ans << endl;
return 0;
}
AOJ/高等排序习题集的更多相关文章
- AOJ/初等排序习题集
ALDS1_1_D-MaximumProfit. Codes: //#define LOCAL #include <cstdio> #include <algorithm> u ...
- 贪心+拓扑排序 AOJ 2456 Usoperanto
题目传送门 题意:给出一条链,比如x连到y,x一定要在y的左边,且代价是这条链经过的点的权值和,问如何排序使得代价最小 分析:类似拓扑排序,先把入度为0的点入队,把指向该点的所有点按照权值排序,保证这 ...
- AOJ/数据结构习题集
ALDS1_3_A-Stack. Description: Write a program which reads an expression in the Reverse Polish notati ...
- AOJ/搜索递归分治法习题集
ALDS1_4_A-LinearSearch. Description: You are given a sequence of n integers S and a sequence of diff ...
- AOJ/树二叉搜索树习题集
ALDS1_7_A-RootedTree. Description: A graph G = (V, E) is a data structure where V is a finite set of ...
- AOJ/堆与动态规划习题集
ALDS1_9_A-CompleteBinaryTree. Codes: //#define LOCAL #include <cstdio> int parent(int i) { ret ...
- AOJ/树与二叉搜索树习题集
ALDS1_7_A-RootedTree. Description: A graph G = (V, E) is a data structure where V is a finite set of ...
- AOJ/搜索与递归及分治法习题集
ALDS1_4_A-LinearSearch. Description: You are given a sequence of n integers S and a sequence of diff ...
- 数据结构与算法之PHP排序算法(归并排序)
一.基本思想 归并排序算法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,使每个子序列有序,再将已有序的子序列合并,得到完全有序的序列.该算法是采用分治法(Divid ...
随机推荐
- 判断N是否是质数,为什么判断到根号N就可以了
N=根号N*根号NN的因数除了根号N,其他都是成对存在的, 且必定一个大于根号N一个小于根号N假设N不是质数,有个因数大于根号N(不是N本身) 则N必定有一个与之对应的小于根号N的因数也就是说,如果2 ...
- 三 MongoDB进阶
1 Limit方法 概念:查询指定数量的数据,该方法接受一个数字参数作为查询记录数的数量 举个例子:查询集合col中最多2条记录数 2 Skip方法 概念:查询到的结果集中,跳过指定数量的数据,该方法 ...
- 关于SequenceInputStream
两个流合并时: package stream.sequence; import java.io.BufferedReader; import java.io.BufferedWriter; impor ...
- ProjectEuler 005题
题目: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any ...
- kubebuilder实战之七:webhook
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Java如何搭建脚手架(自动生成通用代码),创建自定义的archetype(项目模板)
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- 【Python机器学习实战】决策树与集成学习(五)——集成学习(3)GBDT应用实例
前面对GBDT的算法原理进行了描述,通过前文了解到GBDT是以回归树为基分类器的集成学习模型,既可以做分类,也可以做回归,由于GBDT设计很多CART决策树相关内容,就暂不对其算法流程进行实现,本节就 ...
- Docker | 入门 & 基础操作
Dcoker 入门 确保docker 已经安装好了,如没有装好的可以参考:Docker | 安装 运行第一个容器 docker run -it ubuntu /bin/bash docker run ...
- SSH整合(二)
SSH框架实现登录.新闻增删改查.树形菜单 项目结构 pom.xml 网不好不要一次引入太多,容易下不全 <project xmlns="http://maven.apache.org ...
- Python3正则表达式学习笔记
学习前准备:导入re模块 import re 一.re的核心函数 1 - re.compile(pattern[, flags]) 编译正则表达式,速度快 2 - re.match(pattern, ...