杭電 ACM Step(3)
阿新 • • 發佈:2018-11-22
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*));
- 引數:
-
- 待排序陣列首地址
- 陣列中待排序元素數量
- 陣列中各元素的佔用空間
- 指向函式的指標,用於確定排序的順序
程式碼
#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;
}