洛谷-P1923 【深基9.例4】求第 k 小的數

 

題目描述

輸入 nn(n<5000000n<5000000 且 nn 爲奇數) 個數字 a_i(0<a_i<10^9)ai​(0<ai​<109) ,輸出這些數字的第 kk 小的數。最小的數是第 0 小。

輸入格式

輸出格式

輸入輸出樣例

輸入 #1複製

5 1
4 3 2 1 5

輸出 #1複製

2

分析:

這題看起來很簡單,但是必須搞明白一個問題,到底有沒有重複的數字,例如1,2,2,3,5,第2小的數到底是重複的那個2,還是跳過重複的取3?這個糾結了很久,看了看大家的答案,似乎是第一種,就是不管重複,排序好之後直接輸出a[k]就行(數組從0開始),那手擼快排,其他不多說,走你

#include<iostream>
#include<algorithm>
using namespace std;

int n;
int k;
int a[5000005];

void quicksort(int left,int right);
int main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	//quicksort(1,n);
	sort(a,a+n);
	//for(int i=1;i<=n;i++)
	//cout<<a[i]<<" ";
	//cout<<endl;
		/*
	int rank=-1;
	int lasti=-1;
	for(int i=1;i<=n;i++)
	{
		if(a[i]!=lasti)
		{
			rank++;
			if(rank==k)
			{
				cout<<a[i];
				break;
			}
		}
	}
	*/
	cout<<a[k];
	return 0;
}
void quicksort(int left,int right)
{
	int low=left;
	int high=right;
	int mid=a[(low+high)/2];
	do
	{
		while(a[low]<mid) low++;
		while(a[high]>mid) high--;
		if(low<=high)
		{
			swap(a[low],a[high]);
			low++;
			high--;
		}
	}while(low<=high);
	if(left<high) quicksort(left,high);
	if(low<right) quicksort(low,right);
}

三個對了,倆超時,想想也是,五百萬的界限,稍微有點 不好就會超時吧,而且我還考慮到手寫的快排或許沒有sort效率高,專門換成了sort,但是還是超時,問題應該不是在這裏,去看看題解吧

大家好厲害,原來STL還有nth_element這個函數,這個函數主要用來將數組元素中第k小的整數排出來並在數組中就位

用法:nth_element(數組名,數組名+第k小元素,數組名+元素個數)

話不多說,快排刪了,來這個函數

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;

int n;
int k;
long long int a[5000005];

void quicksort(int left,int right);
int main()
{
	cin>>n>>k;
	//scanf("%d",&n);
	//scanf("%d",&k);
	for(int i=0;i<n;i++)
    cin>>a[i];
	//scanf("%d",&a[i]);
	//cin>>a[i];
	nth_element(a,a+k,a+n);
	cout<<a[k];
	return 0;
}

走你,Σ( ° △ °|||)︴,還是超時了,這是爲什麼,就這不到幾十行的代碼,憑什麼你AC我就超時,仔細對比了下和別人的代碼,貌似唯一的不同點就在於我用的是cin,而他用的是scanf? 別開玩笑了,都什麼時候了還在用C語言的scanf,cin不香嗎?但也沒什麼其他好改的了,就先試試吧,改成scanf

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;

int n;
int k;
long long int a[5000005];

void quicksort(int left,int right);
int main()
{
	cin>>n>>k;
	//scanf("%d",&n);
	//scanf("%d",&k);
	for(int i=0;i<n;i++)
	scanf("%d",&a[i]);
	//cin>>a[i];
	nth_element(a,a+k,a+n);
	cout<<a[k];
	return 0;
}

AC了?!!爲什麼,憑什麼,難道我cin幹不過scanf?我不信,我去查查

然而.....https://www.cnblogs.com/limera/p/5405705.html

還是我太年輕了,cin就是幹不過scanf,這篇博客說的很清楚

scanf是格式化輸入,printf是格式化輸出。 
cin是輸入流,cout是輸出流。效率稍低,但書寫簡便。 
 
格式化輸出效率比較高,但是寫代碼麻煩。 
 
流輸出操作效率稍低,但書寫簡便。 
 
cout之所以效率低,正如一樓所說,是先把要輸出的東西存入緩衝區,再輸出,導致效率降低。 

就這樣,scanf效率就是高,而且要注意,這道題最高可是要讀取五百萬個數字,一個數cin或許不會比scanf慢多少,但是再小的時間,乘以五百萬,都是一個大時間,哎,以後要注意了...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章