1. 程式人生 > >杭電 ACM Step(3)

杭電 ACM Step(3)

What Is Your Grade?

這裡寫圖片描述
這裡寫圖片描述

  • 難點
    在這道題中,先按照解題數目和解題時間綜合排序後,還需要計算在同等解題數目的情況下,這個人的解題時間是否在他解題數目相同的人群中的前一半。
#include <stdio.h>
#include <stdlib.h>
typedef struct{
    int P;/*解題數目*/
    int hour;
    int minute;
    int seconds;
    int num;/*原始編號*/
    int score;/*成績*/
}StuInfo;
int
cmp(const StuInfo *p,const StuInfo *q) { if(p->P != q->P) return q->P - p->P; if(p->hour != q->hour) return p->hour - q->hour; if(p->minute != q->minute) return p->minute - q->minute; return p->seconds-q->seconds; } int
cmpn(const StuInfo *p,const StuInfo *q) { return p->num - q->num; } int main() { int num;//學生人數 StuInfo S[105]; int problem[6]; int rank[6]; while(scanf("%d",&num)!= EOF && num !=-1) { for(int i=0;i<6;i++) problem[i]=rank[i]=0; for
(int i=0;i<num;i++) { scanf("%d%d:%d:%d",&S[i].P,&S[i].hour,&S[i].minute,&S[i].seconds); problem[S[i].P]++;/*做對n道題的有多少人*/ S[i].num=i; } for(int i=4;i>0;i--) rank[i]=rank[i+1]+problem[i+1]; qsort(S,num,sizeof(S[0]),cmp); for(int i=0;i<num;i++) { S[i].score=S[i].P*10+50; if(S[i].P==0 || S[i].P==5) continue; /*如果解題數和耗時綜合排序在做對n道題目的前一半,成績加5*/ if(i-rank[S[i].P] < (problem[S[i].P]/2)) S[i].score+=5; } qsort(S,num,sizeof(S[0]),cmpn); for(int i=0;i<num;i++) printf("%d\n",S[i].score); printf("\n"); } return 0; }

排序

這裡寫圖片描述

#include <stdio.h>
#include <stdlib.h>
/*
1.開始的若干個5需要跳過去;
2.最後的若干個5需要跳過去;
3.中間的若干個5需要正確跳過去。
程式中使用了標誌flag,來處理若干個5
*/
int cmp(const void *p,const void *q)
{
    return *(int*)p - *(int*)q;
}
int main()
{
    char figure;
    int val=0,flag=1;
    int values[2000];
    int count=0,i=0;
    while(scanf("%c", &figure)!=EOF)
    {
        if(figure == '\n')/*一次性輸入字串後*/
        {
            if(flag == 0)  values[count++] = val;/*最後一段字元是有效資料*/
            if(count > 0)
            {
                qsort(values, count, sizeof(int), cmp);/*對劃分好的資料快速排序*/
                for(i=0; i<count-1; i++)
                    printf("%d ", values[i]);
                printf("%d\n", values[count-1]);
            }
            val = 0;
            count = 0;
            flag = 1;
        }
        else if(figure == '5')
        {
            if(flag == 0)  values[count++] = val;/*一個有效字串後跟著5的情況*/
            /*這個5出現在有效字串前面*/
            val = 0;
            flag = 1;
        }
        else
        {
            val = val * 10 + figure - '0';/*計算有效資料*/
            flag = 0;
        }
    }
    return 0;
}

考試排名

這裡寫圖片描述
這裡寫圖片描述

解題思路

在這道題目中遇到了一個比較難的地方,就是類似於51(2)這樣的資料該怎麼輸入。看了一下別人的程式碼,發現都是先用字串接收,然後再將其轉為數字。
將所有資料成功傳入後,在面臨排序時,直接呼叫了

qsort()函式

  • 原型:qsort(void*, size_t, size_t,int ()(const void, const void*));
  • 引數:
    1. 待排序陣列首地址
    2. 陣列中待排序元素數量
    3. 陣列中各元素的佔用空間
    4. 指向函式的指標,用於確定排序的順序

    程式碼

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
typedef struct{
    char name[11];/*姓名*/
    int ac; /*解題數目*/
    int time;/*解題時間*/
}ACM;
int char_int(char *p,int mark)/* 將字串中的數字轉化為int型資料 */
{
    if(*p == '-' || *p=='0') /* 題目沒做對,不做統計 */
        return 0;
    int punish=0,temp=0;
    while(*p)
    {
        if(*p == '(')
        {
            while(*(++p) !=')')
                temp=temp*10+*p-'0';
            break;
        }
        punish=punish*10+*p-'0';
        p++;
    }
    return punish+temp*mark;
}
int cmp(const ACM *p,const ACM *q)
{
    if(p->ac != q->ac)
        return q->ac - p->ac;/*先按解題數目排序*/
    if(p->time != q->time)
        return p->time - q->time;/*在解題數目一樣的情況下,再按解題時間排序*/
    return strcmp(p->name,q->name);/*在解題數目和時間一樣的情況下,按名字排序*/
}
int main()
{
    ACM A[1000];
    int num,mark;/* num是考題數,mark是單位罰分數*/
    scanf("%d%d",&num,&mark);
    int i=0,score;
    char a[12];
    while(scanf("%s",A[i].name) != EOF)
    {
        A[i].ac=0;
        A[i].time=0;
        for(int j=0;j<num;j++)
        {
            scanf("%s",a);
            score=char_int(a,mark);
            if(score>0)
            {
                A[i].ac++;
                A[i].time+=score;
            }
        }
        i++;
    }
    qsort(A,i,sizeof(A[0]),cmp);/*引用<stdlib.h>中的快速排序*/
    for(int j=0;j<i;j++)
        printf("%-10s %2d %4d\n",A[j].name,A[j].ac,A[j].time);
    return 0;
}

Rank

這裡寫圖片描述

#include <stdio.h>
typedef struct{
    int Sno;
    int Grade;
} Student;
int main()
{
    Student S[1005];
    Student T;
    int number;
    int a,b;
    int i,flag;
    int flag2=0;
    while(scanf("%d",&number) != EOF)
    {
        i=0;
        while(scanf("%d%d",&a,&b) != EOF && a !=0 && b != 0)
        {
            S[i].Sno=a;
            S[i].Grade=b;
            i++;
        }
        for(int j=0;j<i;j++)
        {   /*選擇排序,但是隻對成績大於等於給定學號的進行排序*/
            flag=j;
            for(int k=j+1;k<i;k++)
                if(S[flag].Grade<S[k].Grade) flag=k;
            T=S[flag];
            S[flag]=S[j];
            S[j]=T;
            if(S[j].Sno == number)
            {
                flag2=j;
                break;
            }
        }
        int Rank=1;
        /*假如有和Jackson分數一樣的同學,Jackson的排名和他們是並列排名*/
        for(int j=0;j<flag2;j++)
            if(S[j].Grade != S[flag2].Grade) Rank++;
        printf("%d\n",Rank);
    }
    return 0;
}