NYOJ---240题小明的调查统计(二)

这个问题其实很长时间之前就可以解决了,但是不想做。以前各种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代码强的多。这样虽然速度会很慢,但是一步一个脚印,只要坚持,就肯定可以走到目的地。

还是那句话,你我共勉:

路漫漫其修远兮,吾将上下而求索。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值