存疑pata1025(已解决)排名

算法笔记105页
我的方法是只排一次名

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//思路: 在输入时记录学校,全输入完成后统一排序,计算排名。
//排名分为两类,总排名i.fr和学校排名i.sch.lr。累计(算人次)排名fr和当前(算不同成绩个数)排名sch.lr。
//总排名累计:直接fr++;
//学校累计:lr[i.sch]++; 
//当前:需找到前一个分数相同的名次, 
//总排名当前:若当前[i]成绩==[i-1]的成绩, 则i.fr=[i-1].fr;
//学校当前: 用samesch[i.sch]=lr; 记录当前最低分的本校排名,当与上一位[i-1]成绩相等时,再判断本校上一名的成绩是否也相等
// 主要是samesch数组,保存的内容:某学校的最低分是否==总的最低分,及更新的条件:因为最低分时时在变,所以需要清零更新。 
struct info{
	char id[14];
	int grade;
	int fr;
	int sch;
	int lr;
}stu[30000];
bool cmp(info a,info b){
	if(a.grade!=b.grade)return a.grade>b.grade;
	else if(strcmp(a.id ,b.id )) {
		return strcmp(a.id ,b.id )<0;
	}
}
int main(){
	int n;
	scanf("%d",&n);
	int cnt=0;
	for(int j=0;j<n;j++){//学校 
		int m;
		scanf("%d",&m);
		for(int i=0;i<m;i++){
			scanf("%s%d",stu[cnt].id,&stu[cnt].grade);
			stu[cnt].sch=j+1; 
			cnt++;
		}
	}
	int lr[n+1]={0},fr=1;
	int samesch[300]={0};//存放当前(最低分)分数相等的所有学校 ,当总排名分数不等时,全部更新为0; 
	sort(stu,stu+cnt,cmp);
	for(int i=0;i<cnt;i++){
		if(i==0) {
			stu[0].fr=fr;
			stu[0].lr=lr[stu[0].sch];
		}
		else{
			if(stu[i].grade==stu[i-1].grade){
				stu[i].fr=stu[i-1].fr;
				if(samesch[stu[i].sch]){	
					stu[i].lr=samesch[stu[i].sch];//ss数组存放某学校的最新(实际)名次 
				}else{
					stu[i].lr=lr[stu[i].sch];//lr数组存放累加名次 
				}	
			}else{
				stu[i].fr=fr;
				stu[i].lr=lr[stu[i].sch];
				memset(samesch,0,sizeof(samesch));
				samesch[stu[i].sch]=stu[i].lr;
			} 
		}
		fr++;
		lr[stu[i].sch]++;
	}
	printf("%d\n",cnt);
	for(int i=0;i<cnt;i++){
		printf("%s %d %d %d\n",stu[i].id,stu[i].fr,stu[i].sch,stu[i].lr+1);
	}
	return 0;
}

用书上方法竟然出错了,但不知错在哪里。
在这里插入图片描述
这里不应该是i

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct info{
	char id[14];
	int grade;
	int lm;//考场号 
	int lr;
}stu[30000];
bool cmp(info a,info b){
	if(a.grade!=b.grade) return a.grade>b.grade;
	else {
		if(strcmp(a.id,b.id)) return strcmp(a.id,b.id)<0;
	}
} 
int main(){
	int n,num=0,j=1;
	scanf("%d",&n);
	while(n--){
		int m;
		scanf("%d",&m);
		for(int i=0;i<m;i++){
			scanf("%s %d",stu[num].id,&stu[num].grade);
			stu[num].lm=j;//考场号 
			num++;
		}
		sort(stu+num-m,stu+num,cmp);
		for(int i=0;i<m;i++){//排名从0开始 
		    if(i){
		    	if(stu[i].grade!=stu[i-1].grade)
				stu[num-m+i].lr=i;
				else stu[num-m+i].lr=stu[num-m+i-1].lr;
			}else stu[num-m+i].lr=0;	
		}
		j++;
 	}
	sort(stu,stu+num,cmp);
	int fr=1; 
	printf("%d\n",num);
	for(int i=0;i<num;i++){
		if(i){
			if(stu[i].grade!=stu[i-1].grade)
				fr=i+1;	
		}
		printf("%s %d %d %d\n",stu[i].id,fr,stu[i].lm,stu[i].lr+1);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值