50分,错哪了呢

P1093 [NOIP2007 普及组] 奖学金

Aheaddd @ 2021-09-17 18:33:30

#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;

struct stu
{
    int a, b, c, all, id;
};
stu stud[305];

bool cmp(stu x, stu y)
{
    return x.all > y.all;
}
bool cmp1(stu x, stu y)
{
    return x.a > y.a;
}
bool cmp2(stu x, stu y)
{
    return x.id < y.id;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        stud[i].id = i;
        cin >> stud[i].a >> stud[i].b >> stud[i].c;
        stud[i].all = stud[i].a + stud[i].b + stud[i].c;
    }
    sort(stud + 1, stud + 1 + n, cmp);
    int ii = 1, flag = 0;
    for (int i = 1; i < n; i++)
    {
        if (stud[i].all == stud[i + 1].all)
        {
            flag = i; break;
        }
    }
    for (int i = 1; i < n; i++)
    {
        if (stud[i].all == stud[i + 1].all)ii++;
    }
    if (ii > 1)
    {
        sort(stud + 1 + flag, stud  + flag + ii, cmp1);
    }
    int flag1 = 0, iii = 1;
    for (int i = flag; i < flag + ii-1; i++)
    {
        if (stud[i].a == stud[i + 1].a)
        {
            flag1 = i; break;
        }
    }
    for (int i = flag; i < flag + ii-1; i++)
    {
        if (stud[i].a == stud[i + 1].a)iii++;
    }
    if (iii > 1)sort(stud + 1 + flag1, stud  + flag1 + iii, cmp2);
    for (int i = 1; i <= 5; i++)
    {
        if (stud[i].id)
        {
            cout << stud[i].id << " " << stud[i].all << endl;
        }
    }

    return 0;
}

by Yike_linen @ 2021-09-17 19:08:07

@Aheaddd

您的这部分代码:

 if (ii > 1)
{
sort(stud + 1 + flag, stud  +       flag +ii, cmp1);
}

会在有相同的总分时,把数组再按语文成绩排一遍(后面同理)。这样的顺序是错误的,在多关键字排序时,更合理的做法是先按优先级最低的排序,再一步一步用优先级最高的方式排序,这样可以保证有序,具体您可以自己推一推。

事实上,cmp函数并不一定要使用多次,这样可以有更简单的写法:

bool cmp(const stu x,const stu y)
 {
    if(x.all!=y.all) return x.all>y.all;
    else if(x.a!=y.a) return x.a>y.a;
    else return a.id<b.id;
 }

这样,可以在输入后直接跑一遍sort,接下来输出即可

如果要看我的代码,点这里


by Aheaddd @ 2021-09-17 20:40:04

@Yike_linen 懂了!非常感谢回答得这么细致,谢谢谢谢!


|