描述 Description | |||
某校的慣例是在每學期的期末考試之後發放獎學金。發放的獎學金共有五種,獲取的條件各自不同: 1) 院士獎學金,每人8000元,期末平均成績高於80分(>80),並且在本學期內發表1篇或1篇以上論文的學生均可獲得; 2) 五四獎學金,每人4000元,期末平均成績高於85分(>85),並且班級評議成績高於80分(>80)的學生均可獲得; 3) 成績優秀獎,每人2000元,期末平均成績高於90分(>90)的學生均可獲得; 4) 西部獎學金,每人1000元,期末平均成績高於85分(>85)的西部省份學生均可獲得; 5) 班級貢獻獎,每人850元,班級評議成績高於80分(>80)的學生幹部均可獲得; 只要符合條件就可以得獎,每項獎學金的獲獎人數沒有限制,每名學生也可以同時獲得多項獎學金。例如姚林的期末平均成績是87分,班級評議成績82分,同時他還是一位學生幹部,那麼他可以同時獲得五四獎學金和班級貢獻獎,獎金總數是4850元。 現在給出若干學生的相關數據,請計算哪些同學獲得的獎金總數最高(假設總有同學能滿足獲得獎學金的條件)。 |
|||
輸入格式 Input Format | |||
輸入的第一行是一個整數N(1 <= N <= 100),表示學生的總數。接下來的N行每行是一位學生的數據,從左向右依次是姓名,期末平均成績,班級評議成績,是否是學生幹部,是否是西部省份學生,以及發表的論文數。姓名是由大小寫英文字母組成的長度不超過20的字符串(不含空格);期末平均成績和班級評議成績都是0到100之間的整數(包括0和100);是否是學生幹部和是否是西部省份學生分別用一個字符表示,Y表示是,N表示不是;發表的論文數是0到10的整數(包括0和10)。每兩個相鄰數據項之間用一個空格分隔。 | |||
輸出格式 Output Format | |||
輸出包括三行,第一行是獲得最多獎金的學生的姓名,第二行是這名學生獲得的獎金總數。如果有兩位或兩位以上的學生獲得的獎金最多,輸出他們之中在輸入文件中出現最早的學生的姓名。第三行是這N個學生獲得的獎學金的總數。 |
這個題目真是把自己的基礎檢查的一清二楚啊,首先是基礎知識不紮實的毛病統統顯露出來了。提交了好幾次才通過,每次否能發現一個問題,囧死了
#include <stdio.h>
#include <Windows.h>
typedef struct student
{
char Name[20];
int Terminal_Grade;
int Class_Grade;
char IsLeader;
char IsWest;
int NumOfPaper;
int money;
}studet;
int main()
{
int n,i,sign;
long int max_money=0,sum = 0;
char *MaxName;
studet Stu[100];
scanf("%d",&n);
sign = n-1;
for(i=0;i<=sign;i++)
{
scanf("%s %d %d %c %c %d",Stu[i].Name,&Stu[i].Terminal_Grade,&Stu[i].Class_Grade,&Stu[i].IsLeader,&Stu[i].IsWest,&Stu[i].NumOfPaper);
}
for (n=0;n<=sign;n++)
{
Stu[n].money = 0;
if(Stu[n].Terminal_Grade>80 && Stu[n].NumOfPaper>=1)
Stu[n].money += 8000;
if (Stu[n].Terminal_Grade>85 && Stu[n].Class_Grade>80)
Stu[n].money += 4000;
if (Stu[n].Terminal_Grade>90)
Stu[n].money += 2000;
if (Stu[n].Terminal_Grade>85 && Stu[n].IsWest =='Y')
Stu[n].money += 1000;
if (Stu[n].Class_Grade>80 && Stu[n].IsLeader =='Y')
Stu[n].money += 850;
sum += Stu[n].money;
if (Stu[n].money > max_money)
{
max_money = Stu[n].money;
MaxName = Stu[n].Name;
}
}
printf("%s\n",MaxName);
printf("%ld\n",max_money);
printf("%ld\n",sum);
system("pause");
return 0;
}
問題1: 關於scanf輸入的問題。
首先自己使用scanf直接輸入
scanf("%s%d%d%c%c%d",Stu[i].Name,&Stu[i].Terminal_Grade,&Stu[i].Class_Grade,&Stu[i].IsLeader,&Stu[i].IsWest,&Stu[i].NumOfPaper);
程序就是檢查讀取錯誤,我爲此還專門寫了一個讀取字符串的函數,後來發現應該不是這個問題,應該是自己沒有添加空格的原因。但是基於規則,讀取字符的時候需要添加空格格式控制,如下寫法也可通過。(字符串碰到空格也結束!!)
scanf("%s%d%d %c %c %d",Stu[i].Name,&Stu[i].Terminal_Grade,&Stu[i].Class_Grade,&Stu[i].IsLeader,&Stu[i].IsWest,&Stu[i].NumOfPaper);
格式字符 | 說明 |
d,i | 用來輸入有符號的十進制數 |
u | 用來輸入無符號的十進制數 |
o | 用來輸入無符號的八進制數 |
x,X | 用來輸入無符號的十六進制數(大小寫作用相同) |
c | 用來輸入當個字符 |
s | 用來輸入字符串,將字符串送到一個字符數組中,在輸入時以非空白字符開始,以讀第一個空白字符結束。字符串以串結束標誌'\0'作爲其最後一個字符 |
f | 用來輸入實數,可以用小數形式或者指數形式輸入 |
e,E,g,G | 與f作用相同,e與f\g可以互相替換,大小寫作用相同 |
l | 用於輸入長整形數據(%ld,%lo,%lx,%lu)以及double類型的數據(%lf,%le) |
h | 用於輸入短整型數據(%hd,%ho,%hx) |
域寬 | 指定輸入數據所佔寬度,域寬應該爲正整數 |
* | 表示輸入項在讀入後不付給相應的變量 |
輸入是不能指定精度
解析:關於scanf的格式化輸入有很多需要注意的地方:
1. 格式控制後面應當是變量地址,而不應該是變量名,此外對於數組要注意,數組名本身就是地址,因此不需要添加&
2. 格式控制字符串中除了格式說明以外還有其他字符,則在輸入數據時應該在對應位置輸入與這些字符相同的字符。
在輸入兩個整數時scanf("%d%d",&a,&b);輸入是兩數之間的空格是可以被忽略的 類似於5.1
3. 在用%c格式輸入字符時,空格字符和轉義字符都將作爲有效字符輸入
4. 在用%s格式輸入字符串是,所有的ASCII碼均可認爲是合法字符,因此必須要用空格或者其他控制字符與其他數據進行區分
5. 在輸入數據(指整數,浮點數)時,遇到以下情況時認爲數據結束:
(1)遇到空格時,或者回車、製表符
(2)按指定的寬度結束,例如"%3d",只取3列
(3)遇到非法輸入。例如"%d"是讀取整數,但是用戶輸入32a,讀取到a時即判定結束。%c只取一個字符(包括空格、轉義等)
上面這些規則雖然如此,但是爲了在寫程序時避免錯誤,還是應該在格式控制時就將數據的分開,如果輸入的數據以空格斷開,那麼格式控制也應該用空格斷開。
問題2:關於讀題仔細的問題,將班幹部的條件搞錯了,知道最後一次才發現問題所在
問題3: 關於打印printf函數,輸出長整形數,自己錯誤的寫爲printf("%dl",money),這顯然是錯誤的,正確的應該是l修飾d printf("%ld",money).
問題多多啊