1. 程式人生 > >PAT 1085 PAT單位排行(25 分)

PAT 1085 PAT單位排行(25 分)

1085 PAT單位排行(25 分)

每次 PAT 考試結束後,考試中心都會發佈一個考生單位排行榜。本題就請你實現這個功能。
輸入格式:
輸入第一行給出一個正整數 N(105​​ ),即考生人數。隨後 N 行,每行按下列格式給出一個考生的資訊:

准考證號 得分 學校

其中准考證號是由 6 個字元組成的字串,其首字母表示考試的級別:B代表乙級,A代表甲級,T代表頂級;得分是 [0, 100] 區間內的整數;學校是由不超過 6 個英文字母組成的單位碼(大小寫無關)。注意:題目保證每個考生的准考證號是不同的。
輸出格式:
首先在一行中輸出單位個數。隨後按以下格式非降序輸出單位的排行榜:

排名 學校 加權總分 考生人數

其中排名是該單位的排名(從 1 開始);學校是全部按小寫字母輸出的單位碼;加權總分定義為乙級總分/1.5 + 甲級總分 + 頂級總分*1.5的整數部分;考生人數是該屬於單位的考生的總人數。
學校首先按加權總分排行。如有並列,則應對應相同的排名,並按考生人數升序輸出。如果仍然並列,則按單位碼的字典序輸出。
輸入樣例:

10
A57908 85 Au
B57908 54 LanX
A37487 60 au
T28374 67 CMU
T32486 24 hypu
A66734 92 cmu
B76378 71 AU
A47780 45 lanx
A72809 100 pku
A03274 45 hypu

輸出樣例:

5
1 cmu 192 2
1 au 192 3
3 pku 100 1
4 hypu 81 2
4 lanx 81 2




這裡寫圖片描述

解析

solution

發現C語言好好寫,在速度上是甩其他語言一大截(逃
這題如果要用C++,就用map。
如果要用C,就要好好規劃程式了,我規劃的程式步驟是:
①處理輸入,每輸入一次,就把字串小寫,成績按BAT更正(用double儲存成績)
②按學校名字排名,方便後面做事
③把每個學校歸檔分配,放在一個新的資料數組裡。
④把定義為double的score現在就取他的整數部分,放在定義為int的score
⑤按int的score排序
⑥輸出


case

最後兩個case沒過,且執行時間為0,代表你的程式超時了,你要重新整理你的程式架構,讓他更快,(建議分析時間複雜度)
最後一個case沒過,你沒有執行上面的步驟4,你是按double的成績排序的。但是題目要求是按int的score排序,所以如果你沒有步驟4,就新增上吧。
最後的case真的神奇,這都能檢查出來。



刷題記錄

這題大家估計都是最後兩個case超時.
我估計我超時的元原因是在新增元素:我是使用自定義的find查詢該考生的學校是否被記錄,如果沒有,則記錄下這個學校。明顯:這樣的時間複雜度是O(N2)。這就是超時的元素。怕是隻能用map了。用C語言真的累,什麼東西都沒有。所以只能得20分
二刷記錄:把思路改一改:
①輸入、,把字串小寫,成績按BAT更正
②按學校排名
③把每個學校歸檔分配,放在 一個新的資料陣列
④輸出
這樣最後兩個監測點是不會超時,但是我的程式碼最後一個監測點沒有通過,(;´д`)ゞ。
三刷記錄:
還是上面的思路,還修改一些地方就能通過了。



一刷:

#include<stdio.h>
#include<string.h>
#include<bits/stdc++.h>
typedef struct{
    char name[10];
    double sum;
    int size;
}school;

int find(school *a,int N,char *string){
    for(int i=0;i<N;i++){
        if(!strcmp(a[i].name,string))
            return i;
    }
    return -1;
}
bool cmp(school a,school b){
    if(a.sum >b.sum)
        return true;
    else if(a.sum == b.sum){
        if(a.size <b.size)
            return true;
        else if(a.size == b.size)
            return (strcmp(a.name,b.name)>0)?false:true;
        else
            return false;
    }
    else
        return false;
}
int main()
{
    int N;
    scanf("%d",&N);
    school* data = (school*)malloc(sizeof(school)*N);
    char temp_id[10];   
    char temp_name[10];
    double score;
    int index,j=0;
    char ch;
    for(int i=0;i<N;i++){
        scanf("%s %lf %s",temp_id,&score,temp_name);    
        int len = strlen(temp_name);    
        for(int i=0;i<len;i++)
            temp_name[i] =tolower(temp_name[i]);
        index = find(data,N,temp_name);
        if(index == -1){
            index = j++;
            strcpy(data[index].name,temp_name);
            data[index].sum=0;
            data[index].size=0;     
        }
        data[index].size++;
        switch(temp_id[0]){
            case 'A':
                data[index].sum+=score;
                break;
            case 'B':
                data[index].sum+=score/1.5;
                break;
            case 'T':
                data[index].sum+=score*1.5;
        }
    }
    std::sort(data,data+j,cmp);
    printf("%d\n",j);
    int k=1,now,sum=0;   
    for(int i=0;i<j;i++){
        now = (int) data[i].sum;
        k = (now ==sum)?k:i+1;
        sum =now;
        printf("%d %s %d %d\n",k,data[i].name,now,data[i].size);
    }

    return 0;
}




二刷

#include<stdio.h>
#include<string.h>
#include<bits/stdc++.h>
typedef struct{
    char name[10];
    double score;
    int size;
}school;

bool cmp1(school a,school b){
    return strcmp(a.name,b.name)>=0?true:false;
}
bool cmp(school a,school b){
    if(a.score >b.score)
        return true;
    else if(a.score == b.score){
        if(a.size <b.size)
            return true;
        else if(a.size == b.size)
            return (strcmp(a.name,b.name)>0)?false:true;
        else
            return false;
    }
    else
        return false;
}
int main()
{
    int N;
    scanf("%d",&N);
    school* data = (school*)malloc(sizeof(school)*N);
    char temp_id[10];
    double score;
    int len;
    for(int i=0;i<N;i++){
        scanf("%s %lf %s",temp_id,&score,(data+i)->name);
        switch(temp_id[0]){
            case 'A':
                (data+i)->score=score;
                break;
            case 'T':
                (data+i)->score=score*1.5;
                break;
            case 'B':
                (data+i)->score=score/1.5;
        }
        len = strlen((data+i)->name);
        for(int j=0;j<len;j++)
            *((data+i)->name+j) = tolower(*((data+i)->name+j));
    }
    std::sort(data,data+N,cmp1);
    school* data1 = (school*)malloc(sizeof(school)*N);
    strcpy(data1->name,data->name);
    data1->score = data->score;
    data1->size++;
    int school_size=0;
    for(int i=1;i<N;i++){
        if(strcmp((data1+school_size)->name,(data+i)->name) == 0){
            (data1+school_size)->score+=(data+i)->score;
            (data1+school_size)->size++;
        }
        else{
            school_size++;
            strcpy((data1+school_size)->name,(data+i)->name);
            (data1+school_size)->score = (data+i)->score;
            (data1+school_size)->size++;
        }
    }
    std::sort(data1,data1+school_size+1,cmp);
    printf("%d\n",school_size+1);
    int k=1,now,sum=0;   
    for(int i=0;i<school_size+1;i++){
        now = (int) data1[i].score;
        k = (now ==sum)?k:i+1;
        sum =now;
        printf("%d %s %d %d\n",k,data1[i].name,now,data1[i].size);
    }

    return 0;
}

三刷程式碼:

#include<stdio.h>
#include<string.h>
#include<bits/stdc++.h>
typedef struct{
    char name[10];
    double score;
    int size;
}school;
typedef struct{
    char name[10];
    double score;
    int score1;
    int size;
}school1;
bool cmp1(school a,school b){
    return strcmp(a.name,b.name)>0?true:false;
}
bool cmp(school1 a,school1 b){
    if(a.score1 >b.score1)
        return true;
    else if(a.score1 == b.score1){
        if(a.size <b.size)
            return true;
        else if(a.size == b.size)
            return (strcmp(a.name,b.name)>0)?false:true;
        else
            return false;
    }
    else
        return false;
}
school data[100001];
school1 data1[100001];
int main()
{
    int N;
    scanf("%d",&N);
    char temp_id[10];
    double score;
    int len;
    for(int i=0;i<N;i++){
        scanf("%s %lf %s",temp_id,&score,(data+i)->name);
        switch(temp_id[0]){
            case 'A':
                (data+i)->score=score;
                break;
            case 'T':
                (data+i)->score=score*1.5;
                break;
            case 'B':
                (data+i)->score=score/1.5;
        }
        len = strlen((data+i)->name);
        for(int j=0;j<len;j++)
            *((data+i)->name+j) = tolower(*((data+i)->name+j));
    }
    std::sort(data,data+N,cmp1);
    strcpy(data1->name,data->name);
    data1->score = data->score;
    data1->size++;
    int school_size=0;
    for(int i=1;i<N;i++){
        if(strcmp((data1+school_size)->name,(data+i)->name) == 0){
            (data1+school_size)->score+=(data+i)->score;
            (data1+school_size)->size++;
        }
        else{
            school_size++;
            strcpy((data1+school_size)->name,(data+i)->name);
            (data1+school_size)->score = (data+i)->score;
            (data1+school_size)->size++;
        }
    }
    for(int i=0;i<school_size+1;i++)
        (data1+i)->score1 = (int)(data1+i)->score;
    std::sort(data1,data1+school_size+1,cmp);
    printf("%d\n",school_size+1);
    int k=1,now,sum=-100;   
    for(int i=0;i<school_size+1;i++){
        now = data1[i].score1;
        k = (now ==sum)?k:i+1;
        printf("%d %s %d %d\n",k,data1[i].name,now,data1[i].size);
        sum =now;
    }

    return 0;
}