警示后人(40/50/60/70/90分进)(错误分析贴)

P1093 [NOIP2007 普及组] 奖学金

Miracle1024 @ 2023-10-02 10:39:28

首先对于这道题我个人的做法是使用结构体+排序的思路。

目前我遇到的问题都是出在 cmp 函数上,在本帖的讲解也围绕 cmp 函数展开,请使用其它方法的同学们自行类比(反正各种解法其实几乎都是换汤不换药)。

本人是以 60-70-40-50-90 的顺序错了一圈的,很有经验。

(本帖又名:我的错误之路)

首先让我们看看我的结构体定义:

struct stu{
    int id;//学号
    int sc;//总分数
    int ch;//语文成绩
}

(不看这个你是看不懂下文的)

然后来说说问题所在。

1

60 分的问题。

这里贴上错误代码:

bool cmp(stu a,stu b){
    if(a.sc==b.sc)return a.id>b.id;
    return a.sc>b.sc;
}

这种错法应该出现比较少。

如果出现这种错误,只能说你有些太粗心了。(但这是我犯的QWQ)

你在忽视了需在依据学号排序前依据语文成绩排序的同时,还把学号的大小于号写反了欸!

2

现在说 70 分,下面贴出 cmp 函数的代码:

bool cmp(stu a,stu b){
    if(a.sc==b.sc)return a.id<b.id;
    return a.sc>b.sc;
}

这时建议你多读几遍题目

你甚至忽视了需在依据学号排序前依据语文成绩排序

3

之后是 40 分。

3,2,1,上代码!

bool cmp(stu a,stu b){
    if(a.sc==b.sc)return a.ch>b.ch;
    if(a.ch==b.ch)return a.id<b.id;
    return a.sc>b.sc;
}

这个问题出现应相对较少,但它也是最难发现的问题之一。

在这段代码中,第二个 if 语句不会被运行,对于语文成绩相等的情况,会在第一个 if 语句后返回 false

对于这个问题,应在第一个 if 语句中加入对于语文成绩是否相等的判断。

4

50 分的场合。

bool cmp(stu a,stu b){
    if(a.sc==b.sc&&a.ch!=b.ch)return a.ch>b.ch;
    if(a.ch==b.ch)return a.id<b.id;
    return a.sc>b.sc;
}

和 40 分的错误性质类似,同样难以发现。

判断语文应该是在总分相等的前提下。

5

最后说 90 分,代码:

bool cmp(stu a,stu b){
    if(a.sc==b.sc&&a.ch!=b.ch){
        return a.ch>b.ch;
        if(a.ch==b.ch&&a.id!=b.id)return a.id<b.id;
    }return a.sc>b.sc;
}

这种情况,首先因为里面那层 ifa.ch==b.ch 会被外面那层 if 筛掉,所以应首先删掉外面那层 if 的第二条判断条件;

然后把外面那层 if 语句里两条语句交换位置就行了。

最后,贴上正确的 cmp 函数代码:

bool cmp(stu a,stu b){
    if(a.sc==b.sc){
        if(a.ch==b.ch&&a.id!=b.id)return a.id<b.id;
        return a.ch>b.ch;
    }return a.sc>b.sc;
}

总结:我在做这题时脑子糊掉了。

(80 分那次是帮别人调代码)(目前还没调出来,希望好心人帮帮忙)

(另:本帖不是 GPT 写的!虽说有些地方我自己也觉得像 hhh)

(再另:这个如果私信管理员申请能发成题解吗 XD)(wokaiwanxiaode)

(再再另:本帖是我10.1半夜码了一大半困得不行去睡觉了第二天起来继续码完的。我大半夜这么认真码字值得您给我一个关注吗 QWQ)


by Miracle1024 @ 2023-10-02 10:40:39

(再再再另:我怎么写这么多另)


by wch666 @ 2023-10-10 18:17:46

感谢,我cmpp写错了


by Ken110802 @ 2023-10-15 10:13:17

感谢


by spindrift @ 2023-11-24 20:33:03

Orz


by spindrift @ 2023-11-24 20:38:06

bool cmp(Student a, Student b) {
    if (a.sum != b.sum) return a.sum > b.sum;
    if (a.cn != b.cn) return a.cn > b.cn;
    return a.id < b.id;
}

还可以这样~哈哈 这是直接把题意翻译的写法


|