洛谷-P1068 分數線劃定

題目描述

世博會志願者的選拔工作正在 A 市如火如荼的進行。爲了選拔最合適的人才,AA市對所有報名的選手進行了筆試,筆試分數達到面試分數線的選手方可進入面試。面試分數線根據計劃錄取人數的150\%150%劃定,即如果計劃錄取mm名志願者,則面試分數線爲排名第m \times 150\%m×150%(向下取整)名的選手的分數,而最終進入面試的選手爲筆試成績不低於面試分數線的所有選手。

現在就請你編寫程序劃定面試分數線,並輸出所有進入面試的選手的報名號和筆試成績。

輸入格式

第一行,兩個整數 n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n)n,m(5≤n≤5000,3≤m≤n),中間用一個空格隔開,其中nn表示報名參加筆試的選手總數,mm表示計劃錄取的志願者人數。輸入數據保證 m \times 150\%m×150%向下取整後小於等於 nn。

第二行到第 n+1n+1 行,每行包括兩個整數,中間用一個空格隔開,分別是選手的報名號 k(1000 ≤ k ≤ 9999)k(1000≤k≤9999)和該選手的筆試成績s(1 ≤ s ≤ 100)s(1≤s≤100)。數據保證選手的報名號各不相同。

輸出格式

第一行,有22個整數,用一個空格隔開,第一個整數表示面試分數線;第二個整數爲進入面試的選手的實際人數。

從第二行開始,每行包含22個整數,中間用一個空格隔開,分別表示進入面試的選手的報名號和筆試成績,按照筆試成績從高到低輸出,如果成績相同,則按報名號由小到大的順序輸出。

輸入輸出樣例

輸入 #1複製

6 3 
1000 90 
3239 88 
2390 95 
7231 84 
1005 95 
1001 88

輸出 #1複製

88 5 
1005 95 
2390 95 
1000 90 
1001 88 
3239 88 

說明/提示

【樣例說明】

m \times 150\% = 3 \times150\% = 4.5m×150%=3×150%=4.5,向下取整後爲44。保證44個人進入面試的分數線爲8888,但因爲8888有重分,所以所有成績大於等於8888 的選手都可以進入面試,故最終有55個人進入面試。

NOIP 2009 普及組 第二題

 

分析:

這道題把我寫吐了,邏輯上並不複雜,然而還是不知道爲什麼只得了10分,現在想來應該適合我的手寫快排有關。第一次寫的使用的二維數組來存儲編號和成績,然後手寫快排進行交換,但是到最後卻WA很多,代碼如下:

#include<iostream>
#include<math.h>

using namespace std;
int n,m;
int people[10000][3];
void quicksort(int left,int right); 
void jg(); 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>people[i][1]>>people[i][2];
	
	quicksort(1,n);
	/*
	cout<<"test "<<endl;
	for(int i=1;i<=n;i++)
	cout<<people[i][1]<<" "<<people[i][2]<<endl;
	*/
	
	jg();
	
	
	int k=floor(m*1.5);
	
	int sum=k;
	int lastcj=people[n-k+1][2];
	
	for(int i=n-k;i>=1;i--)
	{
		if(lastcj==people[i][2])
			sum++;
			
		else
		break;
	}
	
	cout<<lastcj<<" "<<sum<<endl;
	
	for(int i=n;i>=n-sum+1;i--)
	cout<<people[i][1]<<" "<<people[i][2]<<endl;
	return 0;
}
void quicksort(int left,int right)
{
	int low=left;
	int high=right;
	int temp=(low+high)/2;
	do
	{
		while(people[low][2]<people[temp][2]) low++;
		while(people[high][2]>people[temp][2]) high--;
		if(low<=high)
		{
			int t1=people[low][1];
			int t2=people[low][2];
			
			people[low][1]=people[high][1];
			people[low][2]=people[high][2];
			
			people[high][1]=t1;
			people[high][2]=t2;
			low++;
			high--;
		}
	}while(low<=high);
	if(left<high) quicksort(left,high);
	if(right>low) quicksort(low,right);
}
void jg()
{
	int change=1;
	
	while(change)
	{
		change=0;
		for(int i=n;i>1;i--)
		{
			if(people[i][2]==people[i-1][2]&&people[i][1]>people[i-1][1])
			{
				int t1=people[i][1];
				int t2=people[i][2];
				
				people[i][1]=people[i-1][1];
				people[i][2]=people[i-1][2];
				
				people[i-1][1]=t1;
				people[i-1][2]=t2;
				change=1;
			}
		}
	} 
} 

    我先是想讓這個手寫快排變成從大往小(默認是從小往大),然後改了排序算法中的大於小於號,測試用例答案不變,但是跑起來只有10分,我百思不得其解,想着是不是最後那個卡人數的部分弄錯了,然後改了很久,還是10分,我意識到問題或許不在那裏,那就是成績相同,學號小優先錯了?也不對啊,我寫了個jg函數專門就是爲了解決這個問題的,輸出也正常,那難道,是快排算法?

    我有這個想法,因爲我私自改了大於小於號,然後10分,我估計是我改的時候沒注意到其他的,然後導致快排算法出了問題,但是樣例是對的,這就很煩,我也沒有什麼好的數據去進行測試,那沒辦法了,不弄那麼多花裏花哨的了,改成從小到大排,然後一系列全是反序來的,然後20....

    吐了,看看大家的吧,原來大家用了結構體和sort函數??????我不是沒想過sort函數,但是每次涉及到多種情況的比較時,我就覺得sort函數沒法用,它只能從小到大排序,今天算是開了眼界了.題解裏的大神讓我學會了一個新東西,sort排序

    

 #include<algorithm>
   sort(a+m,a+n/*,排序規則*/);  
   //a是數組名,m,n是排序的範圍(從a[m]排到a[n])。 (m與排序規則可以省略,默認m=0,排序規則爲從大到小)

可以自己寫個cmp,來進行sort排序.......話不多說,改一下吧,不用二維數組了,用結構體吧,然後AC了,果然,問題還是出在手寫快排算法上,也不知道究竟是哪裏出了問題,畢竟上道題我手寫快排也AC了,這道題就不行了,以後還是要研究下了,上AC代碼:

#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
struct People{
	int num;
	int score;
};
People people[10000];
int n,m;

bool cmp(People p1,People p2);
 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>people[i].num>>people[i].score;
	sort(people+1,people+1+n,cmp);
	
	
	int k=floor(m*1.5);
	
	int sum=k;
	int lastcj=people[k].score;
	
	for(int i=k+1;i<=n;i++)
	{
		if(lastcj==people[i].score)
			sum++;
			
		else
		break;
	}
	
	cout<<lastcj<<" "<<sum<<endl;
	
	for(int i=1;i<=sum;i++)
	cout<<people[i].num <<" "<<people[i].score <<endl;
	return 0;
}
bool cmp(People p1,People p2)
{
	if(p1.score>p2.score)
	return true;
	if(p1.score<p2.score)
	return false;
	if(p1.score==p2.score)
	{
		if(p1.num<p2.num)
		return true;
		else
		return false;
	}
}

 

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