PAT德才论 BUG

Martin Morning 2019-07-04 09:32:48
用第一个排序,结果一个测试点答案错误,两个点运行超时。然后我把排序换成了快排,测试点错的更多了,调试一下发现,快排似乎没起作用,相当于没调用sort函数一样。

1015 德才论 (25 分)
宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”

现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:

输入第一行给出 3 个正整数,分别为:N(≤10
​5
​​ ),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。

随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:

输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

输入样例:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60
输出样例:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct student
{
long int N;//准考证号
int s1;//德
int s2;//才
int s;//总分
} STU;

void sort(STU s2[],int l,int r)
{
int i,j;
for(i=l;i<=r;i++)
{
int t=i;

for(j=i+1;j<=r;j++)
{

if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 )
{
t=j;

}

}
if(t!=i)
{
STU T=s2[i];
s2[i]=s2[t];

s2[t]=T;
}
}
}

/*
void sort(STU R[], int low,int high) //快排
{
int i,j;
STU t;
i=low;j=high;
if(low<high)
{
t=R[low];
while(i<j)
{
while(i<j&&R[j].s>=t.s)
--j;
if(i<j)
R[i++]=R[j];
while(i<j&&R[i].s<t.s)
++i;
if(i<j)
R[j--]=R[i];

}
R[i]=t;
sort(R,low,i-1);
sort(R,i+1,high);
}
}
*/

int main(int argc, char *argv[]) {
int n,l,h;
scanf("%d%d%d",&n,&l,&h);
int i,j;
STU s[10001];
for(i=0;i<n;i++)//输入学号德才总分
{


scanf("%ld",&s[i].N);
scanf("%d%d",&s[i].s1,&s[i].s2);
s[i].s= s[i].s1+s[i].s2;
}
int k=0;
STU s2[100001];
for(i=0;i<n;i++)//存储第一类考生
{
if(s[i].s1>=80 &&s[i].s2>=80)
s2[k++]=s[i];
}
int d1=k-1;//记录最后一个第一类考生的下标
for(i=0;i<n;i++)//存储第二类考生
{
if(s[i].s1>=80&&s[i].s2<80&&s[i].s2>=60)
s2[k++]=s[i];
}
int d2=k-1;//记录最后一个第二类考生的下标
for(i=0;i<n;i++)//存储第三类考生
{
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)
s2[k++]=s[i];
}
int d3=k-1;//记录最后一个第三类考生的下标
for(i=0;i<n;i++)//第四类考生
{
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2>=60&&s[i].s1<s[i].s2)
s2[k++]=s[i];
}
int d4=k-1;////记录最后一个第四类考生的下标
printf("%d\n",k);

sort(s2,0,d1);
sort(s2,d1+1,d2);
sort(s2,d2+1,d3);
sort(s2,d3+1,d4);

for(i=0;i<k;i++)
{
printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2);
}
}

...全文
189 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Martin Morning 2019-07-06
  • 打赏
  • 举报
回复
引用 15 楼 coo135 的回复:
[quote=引用 7 楼 Martin Morning 的回复:]
[quote=引用 12 楼 coo135 的回复:]
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]能加个Q或者V吗,可以相互讨论,论坛讨论太麻烦了[/quote]

你呀~~~那么粗心~~~我都给你验证过了的。
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)
80换为h,60换为l,每条都去换。
还是给你贴上改过的代码吧~~~记住,要细心点~~不要太暴躁~~



#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct student {
long int N;//准考证号
int s1;//德
int s2;//才
int s;//总分
} STU;

void sort(STU s2[],int l,int r) {
int i,j;
for(i=l; i<=r; i++) {
int t=i;

for(j=i+1; j<=r; j++) {

if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N ) { //修改点1
t=j;
}

}
if(t!=i) {
STU T=s2[i];
s2[i]=s2[t];

s2[t]=T;
}
}
}



int main(int argc, char *argv[]) {
int n,l,h;
scanf("%d%d%d",&n,&l,&h);
int i,j;
STU s[100001];//<===修改点2
for(i=0; i<n; i++) { //输入学号德才总分


scanf("%ld",&s[i].N);
scanf("%d%d",&s[i].s1,&s[i].s2);
s[i].s= s[i].s1+s[i].s2;
}
int k=0;
STU s2[100001];
for(i=0; i<n; i++) { //存储第一类考生
if(s[i].s1>=h &&s[i].s2>=h) //修改点3
s2[k++]=s[i];
}
int d1=k-1;//记录最后一个第一类考生的下标
for(i=0; i<n; i++) { //存储第二类考生
if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l) //修改点4
s2[k++]=s[i];
}
int d2=k-1;//记录最后一个第二类考生的下标
for(i=0; i<n; i++) { //存储第三类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2) //修改点5
s2[k++]=s[i];
}
int d3=k-1;//记录最后一个第三类考生的下标
for(i=0; i<n; i++) { //第四类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6
s2[k++]=s[i];
}
int d4=k-1;////记录最后一个第四类考生的下标
printf("%d\n",k);

sort(s2,0,d1);
sort(s2,d1+1,d2);
sort(s2,d2+1,d3);
sort(s2,d3+1,d4);

for(i=0; i<k; i++) {
printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2);
}
}
[/quote]解决了,

引用 15 楼 coo135 的回复:
[quote=引用 7 楼 Martin Morning 的回复:]
[quote=引用 12 楼 coo135 的回复:]
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]能加个Q或者V吗,可以相互讨论,论坛讨论太麻烦了[/quote]

你呀~~~那么粗心~~~我都给你验证过了的。
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)
80换为h,60换为l,每条都去换。
还是给你贴上改过的代码吧~~~记住,要细心点~~不要太暴躁~~



#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct student {
long int N;//准考证号
int s1;//德
int s2;//才
int s;//总分
} STU;

void sort(STU s2[],int l,int r) {
int i,j;
for(i=l; i<=r; i++) {
int t=i;

for(j=i+1; j<=r; j++) {

if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N ) { //修改点1
t=j;
}

}
if(t!=i) {
STU T=s2[i];
s2[i]=s2[t];

s2[t]=T;
}
}
}



int main(int argc, char *argv[]) {
int n,l,h;
scanf("%d%d%d",&n,&l,&h);
int i,j;
STU s[100001];//<===修改点2
for(i=0; i<n; i++) { //输入学号德才总分


scanf("%ld",&s[i].N);
scanf("%d%d",&s[i].s1,&s[i].s2);
s[i].s= s[i].s1+s[i].s2;
}
int k=0;
STU s2[100001];
for(i=0; i<n; i++) { //存储第一类考生
if(s[i].s1>=h &&s[i].s2>=h) //修改点3
s2[k++]=s[i];
}
int d1=k-1;//记录最后一个第一类考生的下标
for(i=0; i<n; i++) { //存储第二类考生
if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l) //修改点4
s2[k++]=s[i];
}
int d2=k-1;//记录最后一个第二类考生的下标
for(i=0; i<n; i++) { //存储第三类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2) //修改点5
s2[k++]=s[i];
}
int d3=k-1;//记录最后一个第三类考生的下标
for(i=0; i<n; i++) { //第四类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6
s2[k++]=s[i];
}
int d4=k-1;////记录最后一个第四类考生的下标
printf("%d\n",k);

sort(s2,0,d1);
sort(s2,d1+1,d2);
sort(s2,d2+1,d3);
sort(s2,d3+1,d4);

for(i=0; i<k; i++) {
printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2);
}
}
[/quote]

引用 15 楼 coo135 的回复:
[quote=引用 7 楼 Martin Morning 的回复:]
[quote=引用 12 楼 coo135 的回复:]
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]能加个Q或者V吗,可以相互讨论,论坛讨论太麻烦了[/quote]

你呀~~~那么粗心~~~我都给你验证过了的。
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)
80换为h,60换为l,每条都去换。
还是给你贴上改过的代码吧~~~记住,要细心点~~不要太暴躁~~



#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct student {
long int N;//准考证号
int s1;//德
int s2;//才
int s;//总分
} STU;

void sort(STU s2[],int l,int r) {
int i,j;
for(i=l; i<=r; i++) {
int t=i;

for(j=i+1; j<=r; j++) {

if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N ) { //修改点1
t=j;
}

}
if(t!=i) {
STU T=s2[i];
s2[i]=s2[t];

s2[t]=T;
}
}
}



int main(int argc, char *argv[]) {
int n,l,h;
scanf("%d%d%d",&n,&l,&h);
int i,j;
STU s[100001];//<===修改点2
for(i=0; i<n; i++) { //输入学号德才总分


scanf("%ld",&s[i].N);
scanf("%d%d",&s[i].s1,&s[i].s2);
s[i].s= s[i].s1+s[i].s2;
}
int k=0;
STU s2[100001];
for(i=0; i<n; i++) { //存储第一类考生
if(s[i].s1>=h &&s[i].s2>=h) //修改点3
s2[k++]=s[i];
}
int d1=k-1;//记录最后一个第一类考生的下标
for(i=0; i<n; i++) { //存储第二类考生
if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l) //修改点4
s2[k++]=s[i];
}
int d2=k-1;//记录最后一个第二类考生的下标
for(i=0; i<n; i++) { //存储第三类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2) //修改点5
s2[k++]=s[i];
}
int d3=k-1;//记录最后一个第三类考生的下标
for(i=0; i<n; i++) { //第四类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6
s2[k++]=s[i];
}
int d4=k-1;////记录最后一个第四类考生的下标
printf("%d\n",k);

sort(s2,0,d1);
sort(s2,d1+1,d2);
sort(s2,d2+1,d3);
sort(s2,d3+1,d4);

for(i=0; i<k; i++) {
printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2);
}
}
[/quote]通过了,谢谢老哥的帮忙,下次我一定自己注意。
coo135 2019-07-06
  • 打赏
  • 举报
回复
引用 7 楼 Martin Morning 的回复:
[quote=引用 12 楼 coo135 的回复:]
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]能加个Q或者V吗,可以相互讨论,论坛讨论太麻烦了[/quote]

你呀~~~那么粗心~~~我都给你验证过了的。
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)
80换为h,60换为l,每条都去换。
还是给你贴上改过的代码吧~~~记住,要细心点~~不要太暴躁~~



#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct student {
long int N;//准考证号
int s1;//德
int s2;//才
int s;//总分
} STU;

void sort(STU s2[],int l,int r) {
int i,j;
for(i=l; i<=r; i++) {
int t=i;

for(j=i+1; j<=r; j++) {

if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N ) { //修改点1
t=j;
}

}
if(t!=i) {
STU T=s2[i];
s2[i]=s2[t];

s2[t]=T;
}
}
}



int main(int argc, char *argv[]) {
int n,l,h;
scanf("%d%d%d",&n,&l,&h);
int i,j;
STU s[100001];//<===修改点2
for(i=0; i<n; i++) { //输入学号德才总分


scanf("%ld",&s[i].N);
scanf("%d%d",&s[i].s1,&s[i].s2);
s[i].s= s[i].s1+s[i].s2;
}
int k=0;
STU s2[100001];
for(i=0; i<n; i++) { //存储第一类考生
if(s[i].s1>=h &&s[i].s2>=h) //修改点3
s2[k++]=s[i];
}
int d1=k-1;//记录最后一个第一类考生的下标
for(i=0; i<n; i++) { //存储第二类考生
if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l) //修改点4
s2[k++]=s[i];
}
int d2=k-1;//记录最后一个第二类考生的下标
for(i=0; i<n; i++) { //存储第三类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2) //修改点5
s2[k++]=s[i];
}
int d3=k-1;//记录最后一个第三类考生的下标
for(i=0; i<n; i++) { //第四类考生
if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6
s2[k++]=s[i];
}
int d4=k-1;////记录最后一个第四类考生的下标
printf("%d\n",k);

sort(s2,0,d1);
sort(s2,d1+1,d2);
sort(s2,d2+1,d3);
sort(s2,d3+1,d4);

for(i=0; i<k; i++) {
printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2);
}
}
Martin Morning 2019-07-06
  • 打赏
  • 举报
回复
引用 12 楼 coo135 的回复:
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]能加个Q或者V吗,可以相互讨论,论坛讨论太麻烦了
Martin Morning 2019-07-06
  • 打赏
  • 举报
回复
引用 12 楼 coo135 的回复:
[quote=引用 11 楼 Martin Morning 的回复:]
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




[/quote]老铁,费心了。不过很遗憾,并不是这里出的问题,因为我改了之后还是报错
coo135 2019-07-06
  • 打赏
  • 举报
回复
引用 11 楼 Martin Morning 的回复:
[quote=引用 10 楼 coo135 的回复:]
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的[/quote]

是一样的,这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。

早上脑子比较清晰,再看了一遍,找出问题。

STU s[10001]; <=====BUG,少了一位!!!溢出了~~

就那么简单,问题解决了~~~费了我不少时间~~~

存储第三类考生,条件判断:
if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为:
if( s[i].s1<80&&s[i].s1>=60 && s[i].s2>=60 && s[i].s1>=s[i].s2 )比较妥当。




Martin Morning 2019-07-05
  • 打赏
  • 举报
回复
引用 10 楼 coo135 的回复:
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
你的代码和我的意思是一样呀,我换了你的也是错的
coo135 2019-07-05
  • 打赏
  • 举报
回复
你德判断条件不严谨,换成下面德代码。



if(s2[j].s!=s2[t].s ) { //总分不相等时,按总分判断
if(s2[j].s>s2[t].s)
t=j;
} else { // 总分相等
if(s2[j].s1!=s2[t].s1) { //但德 分数不同,根据 德 判断
if(s2[j].s1>s2[t].s1)
t=j;
} else { //总分、德 也相同,根据学号判断
if(s2[j].N<s2[t].N)
t=j;
}
}
Martin Morning 2019-07-05
  • 打赏
  • 举报
回复
引用 8 楼 coo135 的回复:
[quote=引用 7 楼 Martin Morning 的回复:]
[quote=引用 6 楼 coo135的回复:]if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 )
你仅考虑了1:按总分,2:总分相同按德,没有考虑3:总分、德相同,需要按照学号升序排列。

这个测试数据有陷阱的,所以你用测试数据能输出正确结果。但是如果你把:
10000011 85 80
10000003 85 80
这两行位置换一下看看,输出就不对了。

PTA的老师很狡猾的……

你说的对,但是很奇怪,我没加学号的条件运行出来的结果也是对的,你不信可以把给的样例输进去试试。样例学号11在03之前,但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试,发现学号又不能排序了,你知道这是为什么吗[/quote]

道理很简单,你用的是选择排序法,它的排序结果是不稳定的。当a==b时,b有可能出现在a的前面,这个在《数据结构》上有介绍的。如果你用稳定的排序算法,如冒泡、插入等排序法,估计你很快就发现漏了一个判断条件。[/quote]恍然大悟。可是为啥我把学号的条件加上去, if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1||s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N ),提交上去那个测试点还是错误的呢
coo135 2019-07-05
  • 打赏
  • 举报
回复
引用 7 楼 Martin Morning 的回复:
[quote=引用 6 楼 coo135的回复:]if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 )
你仅考虑了1:按总分,2:总分相同按德,没有考虑3:总分、德相同,需要按照学号升序排列。

这个测试数据有陷阱的,所以你用测试数据能输出正确结果。但是如果你把:
10000011 85 80
10000003 85 80
这两行位置换一下看看,输出就不对了。

PTA的老师很狡猾的……

你说的对,但是很奇怪,我没加学号的条件运行出来的结果也是对的,你不信可以把给的样例输进去试试。样例学号11在03之前,但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试,发现学号又不能排序了,你知道这是为什么吗[/quote]

道理很简单,你用的是选择排序法,它的排序结果是不稳定的。当a==b时,b有可能出现在a的前面,这个在《数据结构》上有介绍的。如果你用稳定的排序算法,如冒泡、插入等排序法,估计你很快就发现漏了一个判断条件。
Martin Morning 2019-07-05
  • 打赏
  • 举报
回复
引用 6 楼 coo135的回复:
if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 )
你仅考虑了1:按总分,2:总分相同按德,没有考虑3:总分、德相同,需要按照学号升序排列。

这个测试数据有陷阱的,所以你用测试数据能输出正确结果。但是如果你把:
10000011 85 80
10000003 85 80
这两行位置换一下看看,输出就不对了。

PTA的老师很狡猾的……
你说的对,但是很奇怪,我没加学号的条件运行出来的结果也是对的,你不信可以把给的样例输进去试试。样例学号11在03之前,但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试,发现学号又不能排序了,你知道这是为什么吗
coo135 2019-07-05
  • 打赏
  • 举报
回复
if(s2[j].s>s2[t].s || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 )
你仅考虑了1:按总分,2:总分相同按德,没有考虑3:总分、德相同,需要按照学号升序排列。

这个测试数据有陷阱的,所以你用测试数据能输出正确结果。但是如果你把:
10000011 85 80
10000003 85 80
这两行位置换一下看看,输出就不对了。

PTA的老师很狡猾的……
Martin Morning 2019-07-05
  • 打赏
  • 举报
回复
引用 3 楼 coo135的回复:
你把 #include<stdlib.h>去掉,PTA的stdlib 库中带有qsort排序算法的,冲突了~~。
这个不影响吧,头文件多了又不会影响编译和运行。我用qsort做出来了一个答案,可是我最初写的这个答案我还是没找到错误
Martin Morning 2019-07-05
  • 打赏
  • 举报
回复
引用 1 楼 coo135的回复:
1:你排序的判断条件不够严谨,导致出现一个测试点答案错误。2:这道题需要用N(logN)的排序算法才不会超时。3:你的快速排序算法是错误的。
大佬能看看条件哪里不够严谨吗?快排是我根据天勤书上的代码写的,照说不应该错的,我用普通整型数组也试过确实有效。
coo135 2019-07-05
  • 打赏
  • 举报
回复
你把 #include<stdlib.h>去掉,PTA的stdlib 库中带有qsort排序算法的,冲突了~~。
coo135 2019-07-05
  • 打赏
  • 举报
回复
贴上代码,供你参考。



#include <stdio.h>
#include<stdlib.h>

#define TRUE 1
#define FALSE 0
#define BOOL int

typedef struct _student {
int id;//准考证号
int de;//德
int cai;//才
int level; //等级
} student;

//排序比较函数 ,s1>s2 返回TRUE 其它返回FALSE
BOOL cmp(student * s1, student *s2 ) {
int sum1,sum2;
//计算总分
sum1=s1->de+s1->cai;
sum2=s2->de+s2->cai;

if (s1->level != s2->level) //1:比较等级
return s1->level > s2->level;

if (sum1 < sum2) { //2:等级相同,比较总分
return FALSE;
} else if (sum1 > sum2) {
return TRUE;
} else { //3:总分相同,比较德
if (s1->de < s2->de) {
return FALSE;
} else if (s1->de > s2->de) {
return TRUE;
} else { //4:德也相同,比较id
if (s1->id < s2->id) {
return TRUE;
} else {
return FALSE;
}
}
}
}

//快速排序
void qsort(student stu[], int low,int high) {
int i,j;
student temp;

if(low<high) {
i=low,j=high,temp=stu[i];

while(i<j) {
while(i<j&&!cmp(&stu[j],&temp))
j--;
if(i<j) {
stu[i]=stu[j];
i++;
}

while(i<j&&cmp(&stu[i],&temp))
++i;
if(i<j) {
stu[j]=stu[i];
j--;
}
}
stu[i]=temp;

qsort(stu,low,i-1);
qsort(stu,i+1,high);
}
return;
}

int main() {
int n, l, h;
int i, j;
student stu[100000];
int count = 0; //符合最低标准人数

scanf("%d%d%d", &n, &l, &h);
for (i = 0; i < n; i++) { //输入学号德才总分
scanf("%ld", &stu[i].id);
scanf("%d%d", &stu[i].de, &stu[i].cai);
}

//按标准进行分类,并统计符合标准的人数。
for (i = 0; i < n; i++) {
if (stu[i].de >= h && stu[i].cai >= h) j=5;
else if (stu[i].de >= h && stu[i].cai >= l) j = 4;
else if (stu[i].de >= l && stu[i].cai >= l && stu[i].de >= stu[i].cai) j = 3;
else if (stu[i].de >= l && stu[i].cai >= l) j = 2;
else j=1;
stu[i].level = j;
if (j > 1) count++;
}

qsort(stu,0,n-1); //快速排序

printf("%d\n", count );
for (i = 0; i < count; i++) {
printf("%ld %d %d\n", stu[i].id, stu[i].de, stu[i].cai);
}
return 0;
}
coo135 2019-07-05
  • 打赏
  • 举报
回复
1:你排序的判断条件不够严谨,导致出现一个测试点答案错误。2:这道题需要用N(logN)的排序算法才不会超时。3:你的快速排序算法是错误的。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧