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代码强的多。这样虽然速度会很慢,但是一步一个脚印,只要坚持,就肯定可以走到目的地。

还是那句话,你我共勉:

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



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值