zoukankan      html  css  js  c++  java
  • 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("
    %d
    ", 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("
    ");
    
    	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
    ");
    			break;
    		}
    	}
    	if(i == n) printf("Stable
    ");
    	for(i=0; i<n; ++i) {
    		printf("%c %d
    ", 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("
    ");
    
    	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;
    }
  • 相关阅读:
    题解 SP27102/UVA1747 【Swap Space】
    题解 P1453 【城市环路】
    题解 P5587 【打字练习】
    题解 P5594 【【XR-4】模拟赛】
    git add 的一点说明
    理解 Git 的基本概念 ( Merging Collaborating Rebasing)
    windows 上 Python 通过 SCP 连接linux server
    Neo4j CQL | WITH用法
    Neo4j CQL |create &merge
    Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format(请使用f-string格式化字符串)
  • 原文地址:https://www.cnblogs.com/VincentValentine/p/6799796.html
Copyright © 2011-2022 走看看