PTA甲級 1101 Quick Sort (25分)


首先,先貼柳神的博客

https://www.liuchuo.net/ 這是地址

想要刷好PTA,強烈推薦柳神的博客,和算法筆記

題目原文

There is a classical process named partition in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its left and those larger than the pivot to its right. Given N distinct positive integers after a run of partition, could you tell how many elements could be the selected pivot for this partition?

For example, given N=5 and the numbers 1, 3, 2, 4, and 5. We have:

  • 1 could be the pivot since there is no element to its left and all the elements to its right are larger than it;
  • 3 must not be the pivot since although all the elements to its left are smaller, the number 2 to its right is less than it as well;
  • 2 must not be the pivot since although all the elements to its right are larger, the number 3 to its left is larger than it as well;
  • and for the similar reason, 4 and 5 could also be the pivot.

Hence in total there are 3 pivot candidates.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤105). Then the next line contains N distinct positive integers no larger than 109. The numbers in a line are separated by spaces.

Output Specification:

For each test case, output in the first line the number of pivot candidates. Then in the next line print these candidates in increasing order. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.

Sample Input:

5
1 3 2 4 5

Sample Output:

3
1 4 5

題目大意:

一個數組,要你求出,這個數組裏那些數可以用來當做主元.

主元的定義:

主元左邊的數,都要比主元小,主元右邊的數都要比主元大.

最左的數,就不用考慮左邊,同理最右.

思路如下:

① 判斷一個數,是不是主元,我們只要知道,這個數,左邊最大的數是不是小於這個數,右邊最小的數,是不是大於這個數.

② 我們用兩個數組,一個是leftMax,一個是rightMin,用來記錄,每個數,左邊最大和右邊最小–都不包括自己.

代碼如下

#include<iostream>
#include<vector>
#include<string>
#include<inttypes.h>
using namespace std;


int main(void){
	unsigned int N;
	scanf("%d",&N);
	vector<long long> data(N);
	vector<long long> leftMax(N);
	leftMax.push_back(-1);
	scanf("%I64d",&data[0]);
	for(unsigned int i=1;i<N;++i){
		scanf("%I64d",&data[i]);
		leftMax[i] = max(leftMax[i-1],data[i-1]);	
	}
	vector<long long> rightMin(N);
	rightMin[N-1] = 999999999;
	for(int i=N-2;i>=0;--i){
		rightMin[i] = min(rightMin[i+1],data[i+1]);
	}
	vector<long long> ans;
	for(unsigned int i=0;i<N;i++){
		if(leftMax[i]<data[i]&&rightMin[i]>data[i])
			ans.push_back(data[i]);
	}
	printf("%d\n",ans.size());

	for(unsigned  int i=0;i<ans.size();i++){
		cout<<ans[i];
		if(i<ans.size()-1)
			cout<<" ";
	}

	cout<<"\n";
	return 0;
}

下面是分享的柳神的代碼

地址

#include <iostream>
#include <algorithm>
#include <vector>
int v[100000];
using namespace std;
int main() {
    int n, max = 0, cnt = 0;
    scanf("%d", &n);
    vector<int> a(n), b(n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    sort(a.begin(), a.end());
    for (int i = 0; i < n; i++) {
        if(a[i] == b[i] && b[i] > max)
            v[cnt++] = b[i];
        if (b[i] > max)
            max = b[i];
    }
    printf("%d\n", cnt);
    for(int i = 0; i < cnt; i++) {
        if (i != 0) printf(" ");
        printf("%d", v[i]);
    }
    printf("\n");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章