1001

描述 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);

scanf格式字符
格式字符 說明
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).

問題多多啊

發佈了46 篇原創文章 · 獲贊 102 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章