题目连接:请点击
不知道为什么后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;
}