为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?

Posted

技术标签:

【中文标题】为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?【英文标题】:Why do I need different sorting formats in C++ for sorting arrays and priority queues on this USACO code?为什么我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序? 【发布时间】:2018-10-25 23:36:34 【问题描述】:

我对 C++ 很陌生,并且正在尝试去年的 USACO 问题。这是我下面的代码,它有效,但花了几个小时来摆弄格式。原来我需要

bool sorting(total a, total b) return a.t < b.t;

能够对一组对象(我的优先级队列失败)进行排序,而我需要

struct uppersort 
    bool operator()(bounded a, bounded b) 
    return a.u > b.u;
    
;

能够对优先级队列进行排序(我的数组失败了)。我只是想知道为什么这是真的,以及是否有更简单的方法来做任何一部分。实际上,我也只是在寻找总体上简化我的代码的方法。谢谢!

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct bounded 
    int cow;
    long l;
    long u;
;

struct total 
    long t;
    long whichcow;
    bool begorend;
;

struct uppersort 
    bool operator()(bounded a, bounded b) 
        return a.u > b.u;
    
;

bool sorting(total a, total b) return a.t < b.t;

int main() 
    ofstream fout ("lifeguards.out");
    ifstream fin ("lifeguards.in");
    long n;
    fin >> n;
    vector<bounded> cows(n);
    for(int i=0; i<n; i++) 
        fin >> cows[i].l >> cows[i].u;
        cows[i].cow = i;
    
    vector<total> endpoints(2*n);
    for(int i=0; i<n; i++) 
        endpoints[i].t = cows[i].l;
        endpoints[i].whichcow = i;
        endpoints[i].begorend = 0;
        endpoints[n+i].t=cows[i].u;
        endpoints[n+i].whichcow = i;
        endpoints[n+i].begorend = 1;
    
    sort(endpoints.begin(), endpoints.end(), sorting);
    int containnumber = 0;
    long totaltime = 0;
    vector<long> eachtime(n);
    long prevtime = 0;
    long curtime = 0;
    priority_queue<bounded, vector<bounded>, uppersort> contains;
    for(int i=0; i<2*n; i++) 
        prevtime = curtime;
        curtime = endpoints[i].t;
        if(containnumber==1) 
            eachtime[contains.top().cow] += curtime - prevtime;
        
        if(containnumber >0) 
            totaltime += curtime - prevtime;
        
        if(endpoints[i].begorend==0) 
             contains.push(cows[endpoints[i].whichcow]);
             containnumber++;
         else 
            contains.pop();
            containnumber--;
         
    
    long min = -1;
    for(int i=0; i<n; i++) 
        if(min==-1 || eachtime[i]<min) 
            min = eachtime[i];
        
    
    fout << totaltime-min << endl;

【问题讨论】:

[OT]: bool sorting(total a, total b) return a.t &lt; b.t; 不是排序,而是比较/lessThan/... 关于简化是否可以使用lamda表达式?例如:sort(endpoints.begin(), endpoints.end(), [](const total &amp;a, const total &amp;b) return a.t &lt; b.t; ); 最后一个循环可以是std::min_element 简化是拆分函数:-) 对于工作代码,codereview.stackexchange.com 可能更合适。 【参考方案1】:

sortpriority_queue 都期望提供的类型是可排序的(具有 operator&lt;)。

由于您的boundedtotal 都没有,因此您必须在两种情况下都提供自己的功能。您询问的格式差异只是界面的产物。

在这两种情况下,更简单或更优雅的解决方案是在您的类型上定义 comparison operators。

struct bounded 
    int cow;
    long l;
    long u;
    bool operator<(bound rhs)const
        return u<rhs.u;
    
;

struct total 
    long t;
    long whichcow;
    bool begorend;
    bool operator<(total rhs)const
        return t<rhs.t;
    
;

您应该填写其余的比较运算符以获得良好的形式(或者只是 compare_three_wayoperator&lt;=&gt;,如果您使用的是 c++20 或更高版本)。

【讨论】:

以上是关于为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的选择排序代码不起作用?

C++ 快速排序枢轴优化

我需要一些指导来编写哈希函数来对 ~160,000 个字符串进行排序

对 C++ 字符串的字符进行排序

材料表中是不是有自定义排序功能来对文件大小进行排序?

插入排序函数行为怪异 C++