1. 程式人生 > >九度OJ:題目 1014 排名

九度OJ:題目 1014 排名

題目描述:
    今天的上機考試雖然有實時的Ranklist,但上面的排名只是根據完成的題數排序,沒有考慮每題的分值,所以並不是最後的排名。給定錄取分數線,請你寫程式找出最後通過分數線的考生,並將他們的成績按降序列印。
輸入:

    測試輸入包含若干場考試的資訊。每場考試資訊的第1行給出考生人數N ( 0 < N < 1000 )、考題數M ( 0 < M < = 10 )、分數線(正整數)G;第2行排序給出第1題至第M題的正整數分值;以下N行,每行給出一名考生的准考證號(長度不超過20的字串)、該生解決的題目總數m、以及這m道題的題號(題目號由1到M)。 
    當讀入的考生人數為0時,輸入結束,該場考試不予處理。

輸出:

    對每場考試,首先在第1行輸出不低於分數線的考生人數n,隨後n行按分數從高到低輸出上線考生的考號與分數,其間用1空格分隔。若有多名考生分數相同,則按他們考號的升序輸出。

樣例輸入:
4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0
樣例輸出:
3
CS003 60
CS001 37
CS004 37
0
1

CS000000000000000002 20

[解題思路]

本題我運用的是C++中面向物件的思想解決的

主函式:

<span style="font-size:18px;">int main(){
	while(cin>>N&&N){
		cin>>M>>G;
		int i,j;
		sumPass=0;
		for(i=1;i<=M;i++) cin>>g[i];//輸入各成績
		Student* st=new Student[N+1];//Student物件
		for(i=1;i<=N;i++){
			st[i].inputMessage();//輸入資料
			if(!st[i].signPass) {
				i--;
				N--;
			}
		}
		sortStudent(st);//排序輸出
	}
	return 0;
}</span><span style="font-size:14px;">
</span>
對於Student的類實現程式碼如下
<span style="font-size:18px;">public:
	string stuId;//學生的ID
	int passNum;//通過的(解決)的1題目數目
	int sumGrade;//該學生獲得的總分
	bool signPass;//標記是否過了分數線G
	void inputMessage(){
		cin>>stuId>>passNum;
		sumGrade=0;
		for(int i=1;i<=passNum;i++){
			int grade;
			cin>>grade;
			sumGrade+=g[grade];//得到總分
		}
		if(sumGrade>=G){
			signPass=true;
			sumPass++;
		}
		else signPass=false;
	}
};
</span>

排序輸出程式碼如下
<span style="font-size:18px;">void sortStudent(Student* st){
	int i,j;
	/*
	*選擇排序,可能會很費時間,可以改為相應的其他速度較快的排序
	*/
	for(i=1;i<=N;i++){
		for(j=i+1;j<=N;j++){
			/*
			*兩種情況交換
			*1.總成績較小
			*總成績一樣但是學號比較大
			*/
			if((st[i].sumGrade<st[j].sumGrade)||((st[i].sumGrade==st[j].sumGrade)&&st[i].stuId>st[j].stuId)){
				Student tempSt=st[i];
				st[i]=st[j];
				st[j]=tempSt;
			}
		}
	}
	cout<<sumPass<<endl;
	for(i=1;i<=N;i++){
		cout<<st[i].stuId<<" "<<st[i].sumGrade<<endl;
	}
}</span>
[題目的AC程式碼]
<span style="font-size:18px;">#include<iostream>
#include<string>
using namespace std;

int N,M,G;
int g[11];
int sumPass;
class Student{
public:
	string stuId;//學生的ID
	int passNum;//通過的(解決)的1題目數目
	int sumGrade;//該學生獲得的總分
	bool signPass;//標記是否過了分數線G
	void inputMessage(){
		cin>>stuId>>passNum;
		sumGrade=0;
		for(int i=1;i<=passNum;i++){
			int grade;
			cin>>grade;
			sumGrade+=g[grade];//得到總分
		}
		if(sumGrade>=G){
			signPass=true;
			sumPass++;
		}
		else signPass=false;
	}
};
void sortStudent(Student* st){
	int i,j;
	/*
	*選擇排序,可能會很費時間,可以改為相應的其他速度較快的排序
	*/
	for(i=1;i<=N;i++){
		for(j=i+1;j<=N;j++){
			/*
			*兩種情況交換
			*1.總成績較小
			*總成績一樣但是學號比較大
			*/
			if((st[i].sumGrade<st[j].sumGrade)||((st[i].sumGrade==st[j].sumGrade)&&st[i].stuId>st[j].stuId)){
				Student tempSt=st[i];
				st[i]=st[j];
				st[j]=tempSt;
			}
		}
	}
	cout<<sumPass<<endl;
	for(i=1;i<=N;i++){
		cout<<st[i].stuId<<" "<<st[i].sumGrade<<endl;
	}
}
int main(){
	while(cin>>N&&N){
		cin>>M>>G;
		int i,j;
		sumPass=0;
		for(i=1;i<=M;i++) cin>>g[i];//輸入各成績
		Student* st=new Student[N+1];//Student物件
		for(i=1;i<=N;i++){
			st[i].inputMessage();//輸入資料
			if(!st[i].signPass) {
				i--;
				N--;
			}
		}
		sortStudent(st);//排序輸出
	}
	return 0;
}</span>

[題目網址]