1. 程式人生 > >【PAT乙級題目1015】德才論

【PAT乙級題目1015】德才論

題目描述:
宋代史學家司馬光在《資治通鑑》中有一段著名的“德才論”:“是故才德全盡謂之聖人,才德兼亡謂之愚人,德勝才謂之君子,才勝德謂之小人。凡取人之術,苟不得聖人,君子而與之,與其得小人,不若得愚人。”

現給出一批考生的德才分數,請根據司馬光的理論給出錄取排名。

輸入格式:

輸入第1行給出3個正整數,分別為:N(<=105),即考生總數;L(>=60),為錄取最低分數線,即德分和才分均不低於L的考生才有資格被考慮錄取;H(<100),為優先錄取線——德分和才分均不低於此線的被定義為“才德全盡”,此類考生按德才總分從高到低排序;才分不到但德分到線的一類考生屬於“德勝才”,也按總分排序,但排在第一類考生之後;德才分均低於H,但是德分不低於才分的考生屬於“才德兼亡”但尚有“德勝才”者,按總分排序,但排在第二類考生之後;其他達到最低線L的考生也按總分排序,但排在第三類考生之後。

隨後N行,每行給出一位考生的資訊,包括:准考證號、德分、才分,其中准考證號為8位整數,德才分為區間[0, 100]內的整數。數字間以空格分隔。

輸出格式:

輸出第1行首先給出達到最低分數線的考生人數M,隨後M行,每行按照輸入格式輸出一位考生的資訊,考生按輸入中說明的規則從高到低排序。當某類考生中有多人總分相同時,按其德分降序排列;若德分也並列,則按准考證號的升序輸出。
輸入樣例:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

輸出樣例:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

我的第一思路是像學生成績管理系統一樣,用資料結構,在另外構造四個陣列分別儲存這4類學生在結構體中的下標,氣泡排序分別列印每一類學生的輸出順序。但是敲完之後發現程式碼是如此的繁瑣,出題人的初衷不可能是這樣,最後的執行結果也在意料之中,有三處執行超時。

#include<stdio.h>
//用結構體來做其實沒必要
struct student{
    int
xuehao; int Dscore; int Cscore; int DCsum; }; typedef struct student STU; void Paixu(int n,STU stu[],int Num[]); int main(){ int num; int DCstandard; int DCPri; int count=0; int a1=0,b1=0,c1=0,d1=0; scanf("%d %d %d",&num,&DCstandard,&DCPri); STU stu[num]; int a[num],b[num],c[num],d[num]; for(int i=0;i<num;i++) { scanf("%d %d %d",&stu[i].xuehao,&stu[i].Dscore,&stu[i].Cscore); a[i]=b[i]=c[i]=d[i]=0; stu[i].DCsum=stu[i].Dscore+stu[i].Cscore; if(stu[i].Dscore>=DCstandard&&stu[i].Cscore>=DCstandard) { count++; if(stu[i].Dscore>=DCPri&&stu[i].Cscore>=DCPri) { a[a1]=i; a1++; } else if(stu[i].Dscore>=DCPri&&stu[i].Cscore<DCPri){ b[b1]=i; b1++; } else if(stu[i].Dscore<DCPri&&stu[i].Cscore<DCPri&&stu[i].Dscore>=stu[i].Cscore){ c[c1]=i; c1++; } else{ d[d1]=i; d1++; } } } printf("%d\n",count); Paixu(a1,stu,a); Paixu(b1,stu,b); Paixu(c1,stu,c); Paixu(d1,stu,d); for(int i=0;i<a1;i++){ printf("%d %d %d\n",stu[a[i]].xuehao,stu[a[i]].Dscore,stu[a[i]].Cscore); } for(int i=0;i<b1;i++){ printf("%d %d %d\n",stu[b[i]].xuehao,stu[b[i]].Dscore,stu[b[i]].Cscore); } for(int i=0;i<c1;i++){ printf("%d %d %d\n",stu[c[i]].xuehao,stu[c[i]].Dscore,stu[c[i]].Cscore); } for(int i=0;i<d1;i++){ printf("%d %d %d\n",stu[d[i]].xuehao,stu[d[i]].Dscore,stu[d[i]].Cscore); } return 0; } void Paixu(int n,STU stu[],int Num[]) { int temp; for(int i=1;i<n;i++){ for(int j=0;j<n-i;j++){ if(stu[Num[j]].DCsum<stu[Num[j+1]].DCsum){ temp=Num[j+1]; Num[j+1]=Num[j]; Num[j]=temp; } if(stu[Num[j]].DCsum==stu[Num[j+1]].DCsum) { if(stu[Num[j]].Dscore<stu[Num[j+1]].Dscore){ temp=Num[j+1]; Num[j+1]=Num[j]; Num[j]=temp; } if(stu[Num[j]].Dscore==stu[Num[j+1]].Dscore){ if(stu[Num[j]].xuehao>stu[Num[j+1]].xuehao){ temp=Num[j+1]; Num[j+1]=Num[j]; Num[j]=temp; } } } } } }

參考別人C++寫的程式碼之後,覺得自己用氣泡排序實在是態low了,學習了qsort快排,然後實現了下面的簡單做法。

#include<stdio.h>
#include<stdlib.h>
int compare(const void *a_t, const void *b_t){
    int *a = (int *)a_t, *b = (int *)b_t;
    if(a[3] != b[3]){
        return a[3] - b[3]; //type升序
    }
    else if(a[1] + a[2] != b[1] + b[2]){
        return (b[1] + b[2]) - (a[1] + a[2]); //總分降序
    }
    else if(a[1] != b[1]){
        return b[1] - a[1]; //德分降序
    }
    else{
        return a[0] - b[0]; //學號升序
    }
}
int main(){
    int n,l,h;
    int xuehao,de,cai,type,count=0;
    scanf("%d %d %d",&n,&l,&h);
    int a[n][4];
    for(int i=0;i<n;i++)
    {
        scanf("%d %d %d",&xuehao,&de,&cai);
        //分類 
        if(de >= l && cai >= l){

            if(de >= h && cai >= h){
                type = 1;
            }
            else if(de >= h && cai < h){
                type = 2;
            }
            else if(de < h && cai < h && de >= cai){
                type = 3;
            }
            else{
                type = 4;
            }
        }else{
            type=0;
            count++; 
        }
        a[i][0]=xuehao;
        a[i][1]=de;
        a[i][2]=cai;
        a[i][3]=type;

    }
    qsort(&a[0],n,sizeof(a[0]),compare);
    printf("%d\n", n - count);
    for(int i = count; i < n; i++)
    {
        printf("%d %d %d\n", a[i][0], a[i][1], a[i][2]);
    }
    return 0;
}

相關推薦

PAT乙級題目1015德才

題目描述: 宋代史學家司馬光在《資治通鑑》中有一段著名的“德才論”:“是故才德全盡謂之聖人,才德兼亡謂之愚人,德勝才謂之君子,才勝德謂之小人。凡取人之術,苟不得聖人,君子而與之,與其得小人,不若得愚人。” 現給出一批考生的德才分數,請根據司馬光的理論給出錄取

PAT 乙級(Basic Level)德才

呃,這次好尷尬,我發現自己對Java還不是一般的不瞭解。一個題目,暴露了好多問題。出題者的意圖基本沒get到,連內部類都是排序的時候才發現的。 一、難點   排序要求是先按總分從高到低排,如果總分相同則對比德分,按德分從高到低往下排,若德分也相同,則按准考證號大小從小到大往

PAT 乙級(Basic Level)福爾摩斯的約會

唉,原先不知道怎麼操作字串,找到了一個答案。結果6個測試點中有3個錯誤,測了好久還是找不到錯誤在哪,結果又百度到一份答案,居然通過了,對比了半天還是不知道錯誤在哪裡,頭暈,先存起來,下次再找,這個題目做了一天快到,噁心死了。我果然很水。 錯誤答案原始碼: import

PAT乙級1090 危險品裝箱

集裝箱運輸貨物時,我們必須特別小心,不能把不相容的貨物裝在一隻箱子裡。比如氧化劑絕對不能跟易燃液體同箱,否則很容易造成爆炸。 本題給定一張不相容物品的清單,需要你檢查每一張集裝箱貨品清單,判斷它們是否能裝在同一只箱子裡。 輸入格式: 輸入第一行給出兩個正整數:N (≤10​4​

PAT乙級1089 狼人殺-簡單版

以下文字摘自《靈機一動·好玩的數學》:“狼人殺”遊戲分為狼人、好人兩大陣營。在一局“狼人殺”遊戲中,1 號玩家說:“2 號是狼人”,2 號玩家說:“3 號是好人”,3 號玩家說:“4 號是狼人”,4 號玩家說:“5 號是好人”,5 號玩家說:“4 號是好人”。已知這 5 名玩家中有 2 人扮演狼人角

PAT乙級1088 三人行

子曰:“三人行,必有我師焉。擇其善者而從之,其不善者而改之。” 本題給定甲、乙、丙三個人的能力值關係為:甲的能力值確定是 2 位正整數;把甲的能力值的 2 個數字調換位置就是乙的能力值;甲乙兩人能力差是丙的能力值的 X 倍;乙的能力值是丙的 Y 倍。請你指出誰比你強應“從之”,誰比你弱應“改之”

PAT乙級1087 有多少不同的值

當自然數 n 依次取 1、2、3、……、N 時,算式 ⌊n/2⌋+⌊n/3⌋+⌊n/5⌋ 有多少個不同的值?(注:⌊x⌋ 為取整函式,表示不超過 x 的最大自然數,即 x 的整數部分。) 輸入格式

PAT乙級1086 就不告訴你

做作業的時候,鄰座的小盆友問你:“五乘以七等於多少?”你應該不失禮貌地圍笑著告訴他:“五十三。”本題就要求你,對任何一對給定的正整數,倒著輸出它們的乘積。 輸入格式: 輸入在第一行給出兩個不超過 1000 的正整數 A 和 B,其間以空格分隔。 輸出格式: 在一行中倒著輸出 A

PAT乙級1084 外觀數列

外觀數列是指具有以下特點的整數序列: d, d1, d111, d113, d11231, d112213111, ... 它從不等於 1 的數字 d 開始,序列的第 n+1 項是對第 n 項的描述。比如第 2 項表示第 1 項有 1 個 d,所以

PAT乙級1083 是否存在相等的差

給定 N 張卡片,正面分別寫上 1、2、……、N,然後全部翻面,洗牌,在背面分別寫上 1、2、……、N。將每張牌的正反兩面數字相減(大減小),得到 N 個非負差值,其中是否存在相等的差? 輸入格式: 輸入第一行給出一個正整數 N(2 ≤ N ≤ 10

PAT乙級1081 檢查密碼

本題要求你幫助某網站的使用者註冊模組寫一個密碼合法性檢查的小功能。該網站要求使用者設定的密碼必須由不少於6個字元組成,並且只能有英文字母、數字和小數點 .,還必須既有字母也有數字。 輸入格式: 輸入第一行給出一個正整數 N(≤ 100),隨後 N 行,每行給出一個使用者設

PAT乙級1080 MOOC期終成績

對於在中國大學MOOC(http://www.icourse163.org/ )學習“資料結構”課程的學生,想要獲得一張合格證書,必須首先獲得不少於200分的線上程式設計作業分,然後總評獲得不少於60分(滿分100)。總評成績的計算公式為 G=(G​mid−term​​×40%+

PAT乙級1079 延遲的迴文數

給定一個 k+1 位的正整數 N,寫成 a​k​​⋯a​1​​a​0​​ 的形式,其中對所有 i 有 0≤a​i​​<10 且 a​k​​>0。N 被稱為一個迴文數,當且僅當對所

PAT乙級1082 射擊比賽

本題目給出的射擊比賽的規則非常簡單,誰打的彈洞距離靶心最近,誰就是冠軍;誰差得最遠,誰就是菜鳥。本題給出一系列彈洞的平面座標(x,y),請你編寫程式找出冠軍和菜鳥。我們假設靶心在原點(0,0)。 輸入格式: 輸入在第一行中給出一個正整數 N(≤ 10 000)。隨後 N 行,每行按

PAT乙級1054 求平均值

本題的基本要求非常簡單:給定 N 個實數,計算它們的平均值。但複雜的是有些輸入資料可能是非法的。一個“合法”的輸入是 [−1000,1000] 區間內的實數,並且最多精確到小數點後 2 位。當你計算平均值的時候,不能把那些非法的資料算在內。 輸入格式: 輸入第一行給出正整

PAT乙級1056 組合數的和

給定 N 個非 0 的個位數字,用其中任意 2 個數字都可以組合成 1 個 2 位的數字。要求所有可能組合出來的 2 位數字的和。例如給定 2、5、8,則可以組合出:25、28、52、58、82、85,它們的和為330。 輸入格式: 輸入在第一行中給出 N(1 < 

PAT乙級1060 愛丁頓數

英國天文學家愛丁頓很喜歡騎車。據說他為了炫耀自己的騎車功力,還定義了一個“愛丁頓數” E ,即滿足有 E 天騎車超過 E 英里的最大整數 E。據說愛丁頓自己的 E 等於87。 現給定某人 N 天的騎車距離,請你算出對應的愛丁頓數 E(≤N)。 輸入格式: 輸入第一行給出

PAT乙級1062 最簡分數

一個分數一般寫成兩個整數相除的形式:N/M,其中 M 不為0。最簡分數是指分子和分母沒有公約數的分數表示形式。 現給定兩個不相等的正分數 N​1​​/M​1​​ 和 N​2​​/M​2​​,要求你按從小到大的順序列出它們之間分母為 K 的最簡分數。 輸入格式: 輸入在一

PAT乙級1065 單身狗

“單身狗”是中文對於單身人士的一種愛稱。本題請你從上萬人的大型派對中找出落單的客人,以便給予特殊關愛。 輸入格式: 輸入第一行給出一個正整數 N(≤ 50 000),是已知夫妻/伴侶的對數;隨後 N 行,每行給出一對夫妻/伴侶——為方便起見,每人對應一個 ID 號,為 5

PAT乙級1066 影象過濾

影象過濾是把影象中不重要的畫素都染成背景色,使得重要部分被凸顯出來。現給定一幅黑白影象,要求你將灰度值位於某指定區間內的所有畫素顏色都用一種指定的顏色替換。 輸入格式: 輸入在第一行給出一幅影象的解析度,即兩個正整數 M 和 N(0<M,N≤500),另外是待過濾的