L2-027. 名人堂与代金券

详解:

分数是怎么没掉的:

1.strcmp:

一开始我是这样写的:

return strcmp(a.yx,b.yx);

学长粗略看了一下:
return strcmp(a.yx,b.yx)==-1;

后来……

return strcmp(a.yx,b.yx)==-1?1 : 0 ;//有差别吗你个二傻子?

甚至我抄别人的把char[]换成了string,日常迷信……

实际上strcmp返回的是两个字符串第一个不相等的地方的差值,比如a(上)和c(下)就会返回-2.

所以正确的姿势是

return strcmp(a.yx,b.yx)<0;

2.其他人提到了编号,我对这个的解读是:
比如给你5个人,老师划线是前三,然而这时候有两个第一,三个第三,你编号到此就结束。当你已经输出五个人的时候,因为你是按照只要名次还有没满足大于k就继续输出的原则,然而这时候后面的名次永远是0,就会出现一直打印0 0 \n的情况。那么为什么编号往后编一个就可以避免呢?因为往后是没有分数纪录的,所以此时的名次就会被置为6,于是程序遇到这个名次就可以结束了。上图为证:


0 代表mc[5], 
6代表被设置名次后的mc[5].



当然另外一种方法是判断当前输出人数是否已经全部输出完了(输出了n个人)。
代码:
#include<bits/stdc++.h>
using namespace std;
#define N 100005
struct ele{
	char yx[20];
	int fs;
	bool friend operator <(ele a,ele b)
	{
		if(a.fs!=b.fs)
		return a.fs>b.fs;
		else
		return strcmp(a.yx,b.yx)<0;
	}
}s[N];
int sum=0;
int n,g,k;
int main()
{
	memset(s,'\0',sizeof(s));
	cin>>n>>g>>k; 
	int i;
	for(i=0;i<n;i++)
	{
		scanf("%s%d",s[i].yx,&s[i].fs);
		if(s[i].fs>=60&&s[i].fs<g)
		sum+=20;
		else if(s[i].fs<=100&&s[i].fs>=g)
		sum+=50;
	}
	cout<<sum<<endl;
	sort(s,s+n);
	int mc[N];
	mc[0]=1;
	//cout<<mc[5]<<endl; 
	for(i=1;i<n+1;i++)
	{
		if(s[i].fs==s[i-1].fs)
		mc[i]=mc[i-1];
		else
		mc[i]=i+1;//第一种解决方法 
	}
	//cout<<mc[5]<<endl; 
	int jb=0;
	while(1)
	{
		//if(jb==n) break; 第二种解决方法 
		if(mc[jb]<=k)
		{
			printf("%d %s %d\n",mc[jb],s[jb].yx,s[jb].fs);
			jb++;
		}
		else break;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值