PAT 1055 集体照(后3测试点未过 已通过)

题目连接:请点击
不知道为什么后3测试点一直未过,第4与6测试点提示段溢出,第5测试点答案错误。求帮助。。。
————————————————————
发布之前就已经找了好久的bug,然后又找了1个小时的bug终于才发现问题 问题分析写在注解
----------------正文---------------------------------------
思路:首先,定义结构体,然后按照题目要求先身高降序后姓名升序排列。其次,就是怎样解决让每一排的人按照题目要求那样站(次高 最高 次次高)。代码2是之前错的(后已更改通过,只是当前以为可能是代码时间长,所以后来有写了代码1,但其实不是此问题)。代码1更易理解,代码2繁琐。
代码1,定义mid表示中间的位置(即最高者),定义int型cnt来表示当前次高(或其他人)应该距最高者的距离,然后用mid-cnt(次高,左)与mid+cnt(次次高,右)来表示没人应在位置,用string类型的数组来存储每一排应站位置人的姓名。这样可以直接在一排结束后直接输出,不需要像代码2增加start的定义。
代码2中,在结构体中增加一个int型的pos来表示每个人应该在哪个位置,由题定义mid表示中间的位置(即最高者),定义int型cnt来表示当前次高(或其他人)应该距最高者的距离,然后用mid-cnt(次高,左)与mid+cnt(次次高,右)来表示没人应在位置,存入结构体pos中。而由于,后面还需要对结构体按照pos从小到大排序,所以需要让每一排人所在的位置转换成在队列中所处的总位置,也因此需要增加一个start用于记录当前排往前的所有人数。
注解:
1.之前错在compare(str1,str2)函数(头文件cstring)。当str1>str2时,返1;当str1<str2时,返-1;当str1=str2时,返0。然而第一次,在if条件是t1.name.compare(t2.name)这样只要二者不相等就会返回真导致后3个测试点一直未通过
2.需要注意在计算每排人应处位置时,由于for循环是j=j+2,应当判断j+1是否大于当前排的人数。因为每次加2,当次高人位置确定后,无法得知次次高在当前排是否还存在。否则会有数组越界。
AC代码1:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Team{
	string name;
	int height;
};
bool cmp(Team t1,Team t2){
	if(t1.height!=t2.height) return t1.height>t2.height;
	else return t1.name<t2.name;
}
int main(){
	int N,K;
	cin>>N>>K;
	Team team[N]; 
	for(int i=0;i<N;i++) cin>>team[i].name>>team[i].height;
	sort(team,team+N,cmp);//sort()头文件是<algorithm>
	int row=N/K,lastRow,count=0;//row表示每排人数 lastRow最后一排人数 count队列中的位置 
	if(N%K==0) lastRow=row;//若整除则无多余的人 否则多余的人站后面 
	else lastRow=row+N%K;//否则多余的人站后面
	for(int i=0;i<K;i++){
		int r;//每排的人数
		if(i==0) r=lastRow;
		else r=row;
		string n[r];//下标对应当前排的位置 存储应站在此位置的人名 
		int mid=r/2+1,cnt=1;//mid是每排最高所占位置 cnt表示相距最高者距离 
		n[mid-1]=team[count].name; 
		count++;
		for(int j=1;j<r;j+=2){
			n[mid-1-cnt]=team[count].name ;//站高者左 
			count++;
			if((j+1)==r) break;
			n[mid-1+cnt]=team[count].name ;//站高者右 
			count++;
			cnt++;
		} 
		for(int j=0;j<r;j++){
			cout<<n[j];
			if(j!=r-1) cout<<" "; 
		}
		cout<<endl;
	} 
	
	return 0;
}

AC代码2:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Team{
	string name;
	int height;
	int pos;//此人应站位置 
};
/*此前错误原因
bool cmp1(Team t1,Team t2){
	if(t1.height>t2.height) return true;
	else if(t1.height<t2.height) return false;
	else {
		if(t1.name.compare(t2.name)) return true;
		else return false; 
	}
}*/
bool cmp1(Team t1,Team t2){
	if(t1.height!=t2.height) return t1.height>t2.height;
	else return t1.name<t2.name;
}
bool cmp2(Team t1,Team t2){
	if(t1.pos<t2.pos) return true;
	else return false;
}
int main(){
	int N,K;
	cin>>N>>K;
	Team team[N]; 
	for(int i=0;i<N;i++) cin>>team[i].name>>team[i].height;
	sort(team,team+N,cmp1);//sort()头文件是<algorithm>
	int row=N/K,lastRow,start=0;//row表示每排人数 lastRow最后一排人数
	if(N%K==0) lastRow=row;//若整除则无多余的人 否则多余的人站后面 
	else lastRow=row+N%K;//否则多余的人站后面
	for(int i=0;i<K;i++){
		int r;//每排的人数
		if(i==0)r=lastRow;
		else {
			r=row;
			start=lastRow+row*(i-1);//当前排第一人在队列的总位置 
		} 
		int mid=r/2+1,cnt=1;//mid是每排最高所占位置 cnt表示相距最高者距离 
		team[start].pos=start+mid-1;//当前排最高者站中间 由于下标从0开始 所以mid-1 
		for(int j=start+1;j<start+r;j+=2){
			team[j].pos=start+mid-1-cnt;//次高站高者左 
			if((j+1)>=start+r) break;
			team[j+1].pos=start+mid-1+cnt;//次次站高者右 
			cnt++;
		} 
	} 
	sort(team,team+N,cmp2);//将队列按应站位置排序 
	int n=0;
	for(int i=0;i<K;i++){
		int r;
		if(i==0) r=lastRow;
		else r=row;
		for(int j=0;j<r;j++) {
			cout<<team[n].name;
			if(j!=r-1) cout<<" ";
			n++;//输出排队人数++ 
		}
		cout<<endl;
	} 
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值