这个问题其实很长时间之前就可以解决了,但是不想做。以前各种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代码强的多。这样虽然速度会很慢,但是一步一个脚印,只要坚持,就肯定可以走到目的地。
还是那句话,你我共勉:
路漫漫其修远兮,吾将上下而求索。