這個問題其實很長時間之前就可以解決了,但是不想做。以前各種WA,在心裏留下了陰影。我就打算等到自己的實力提升到一定境界之後輕而易舉的解決它,那樣就可以建立強大的自信。嘿嘿······這個題跟杭電的那道海選女主角很相似。但是不同的是這道題需要多加一層判斷。對成績進行排名,需要考慮到並列名次。
解題思路:
定義結構體,用結構體儲存班級,學號,成績,名次。然後用sort排序。不過需要在最開始的地方寫一個排序函數,實現先對成績排序,成績相同在對班級排序,班級相同再對學號排序。
因爲要輸出第m名同學的班級和學號,所以我們要在最後加層判斷。
思路就是這樣。下面就是寫代碼實現這個目標。
各位看官注意一下我寫的註釋。可能會有豁然開朗的感覺。
原題地址:點擊打開鏈接。
代碼如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct chenji
{
int bj;//班級編號
int xh;//學號
int cj;//數學成績
int mc;//名次
} c[100001];
bool comp(chenji x,chenji y)//此處是排序函數。
{
if(x.cj<y.cj) return true;//判斷成績是否相同。
if(x.cj==y.cj&&x.bj<y.bj)return true;//倘若成績相同,比較班級。
if(x.cj==y.cj&&x.bj==y.bj&&x.xh<y.xh)return true;//若成績相同,班級相同,比較學號。
else return false;
}
int main()
{
int i,j,k,l,n,m,count=0,s,a;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)//把數據儲存到結構體裏面
{ scanf("%d",&s);
for(j=1;j<=s;j++)
{
c[count].bj=i;//此處count只能這樣寫,不可以寫成count++,不然會把數據儲存到下個結構體裏面。
c[count].xh=j;
scanf("%d",&k);
c[count].cj=k;
count++;//這時自加,可以使數據儲存到下個編號的結構體中去。
}
}
sort(c,c+count,comp);
l=1;//此處的l進行標記排名
c[count-1].mc=1;//把最後一個的排名賦值爲1,避免訪問到非法空間
for(i=count-2;i>=0;i--)
{if(c[i].cj==c[i+1].cj)//進行判斷,是否與後面的成績相同
c[i].mc=l;
else
c[i].mc=++l;
}
for(i=1;i<=m;i++)
{
scanf("%d",&a);
for(j=0;j<count;j++)//因爲題目要求是按照班級、學號從小到大輸出,故從0開始
{
if(c[j].mc==a)
printf("%d %d\n",c[j].bj,c[j].xh);
}
}return 0;
}
再次感覺到隨手寫註釋的必要。因爲如果代碼很長的話自己都不知道定義的那些變量是什麼意思了。這個代碼有不少是我做對之後又添加上去的,但是有些註釋是自己之前寫的過程中寫成的。所以以後一定要養成寫註釋的習慣。
在這裏我也想表達一下自己的一點感觸:可能很多像我的小菜鳥遇到什麼難題之後就會隨手百度,谷歌之類的,直接搜索代碼,提交上去。然後就心安理得的把這個題目丟到一邊了。我始終覺得這不是什麼王道,因爲一個人如果基礎不夠紮實的話,那他也肯定走不遠。很多時候思考一下,放一段時間然後再做就會發現很多問題都豁然開朗了。哪怕是看看別人的思路,自己思考一下,然後敲出代碼來,也比直接copy代碼強的多。這樣雖然速度會很慢,但是一步一個腳印,只要堅持,就肯定可以走到目的地。
還是那句話,你我共勉:
路漫漫其修遠兮,吾將上下而求索。