luogu1051:谁拿了最多的奖学金:双关键字排序模板

题目连接:该题是luogu试炼场的2-4:T2


题目大意:
1 给出各人的成绩和获奖信息,求出各自的奖金;

2 排序输出最高的奖学金;

3 奖金相同的,输出编号最早的;


解题思路:
1 主要是掌握二分排序的进阶:双关键排序:成绩相同的时候,输入较早(编号较小)的排在前面


上代码:

//luogu1051:谁拿了最多奖学金 
//双关键字排序模板:分数相同的时候,序号小的先输出 
//1 在快排的基础上,加上多一重比较
//2 分数相同的情况,比较序号
 
#include<cstdio>

int n,su=0;
struct nod{char na[50];int s,o;nod(){s=0;}}e[110];

void px(int l,int r)
{
	int x=l,y=r,m=e[(l+r)/2].s,m2=e[(l+r)/2].o;
	while(x<=y)
	{
		while(e[x].s>m||(e[x].s==m&&e[x].o<m2)) x++;//双关键字的精髓 
		while(e[y].s<m||(e[y].s==m&&e[y].o>m2)) y--;//分数相同比序号 
		if(x<=y)
		{
			nod t=e[x];e[x]=e[y];e[y]=t;
			x++;y--;
		}
	}
	if(x<r) px(x,r);
	if(l<y) px(l,y);
}

int main()
{
	
	int x,y,z;
	char a,b;
	//期末平均成绩,x;
	//班级评议成绩,y;
	//是否是学生干部,a;
	//是否是西部省份学生,b;
	//以及发表的论文数,z。
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s%d%d %s %s%d",&e[i].na,&x,&y,&a,&b,&z);
		e[i].o=i;
		if(x>80&&z>=1) e[i].s+=8000;
		if(x>85&&y>80) e[i].s+=4000;
		if(x>90) e[i].s+=2000;
		if(x>85&&b=='Y') e[i].s+=1000;
		if(y>80&&a=='Y') e[i].s+=850;
		su+=e[i].s;
	}
	
	px(1,n); 
	
	printf("%s\n%d\n%d",e[1].na,e[1].s,su);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liusu201601/article/details/88635932