首页 > 试题广场 >

程序的输出为( )

[单选题]
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
struct stsort{
bool operator () (const int a, const int b) const{
if(gcd(30, a) < gcd(30, b)){
return 1;
}
else if(gcd(30, a) == gcd(30, b)){
return a < b;
}
else return 0;
}
};
int main(){
int n = 5;
priority_queue<int, vector<int>, stsort>q;
for(int i = 1; i <= n; ++i){
q.push(i);
}
for(int i = 1; i <= n; ++i){
printf("%d", q.top());
q.pop();
}
return 0;
}


程序的输出为( )
  • 53421
  • 53241
  • 12435
  • 14235

惯例先给这个垃圾代码排个版:

#include <cstdio>
#include <queue>

using namespace std;

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

struct stsort {
    bool operator()(int a, int b) const {
        auto gcda = gcd(30, a), gcdb = gcd(30, b);
        return gcda < gcdb ||
            (gcda == gcdb && a < b);
    }
};

int main() {
    priority_queue<int, vector<int>, stsort> q;
    for (int i = 1; i <= 5; ++i)
        q.push(i);
    for (int i = 1; i <= 5; ++i) {
        printf("%d", q.top());
        q.pop();
    }
}

从它给的比较器能看出来,相当于是对元素对<a与30的最大公约数, a>按字典序排列,也就是等价于:

int main() {
    priority_queue<pair<int, int>> q;
    for(int i=1; i<=5; ++i)
        q.push({ gcd(30, i), i });
    for(int i=1; i<=5; ++i) {
        printf("%d", q.top().second);
        q.pop();
    }
}

默认比较器std::lessstd::pair排序就是按字典序小于关系比较。

最后要注意一点是,如果优先队列std::priority_queue是按照“小于”关系比较的话得到的是大顶堆,最“大”的元素在堆顶,和std::sort是相反的。

发表于 2019-08-29 15:03:45 回复(1)
这个题思考了很久,总是想不出为什么不是12435。我认为是问题出在了二元谓词的参数的赋值顺序,按照标准C/C++,函数参数是从右至左依次入栈,所以第一次比较,二元谓词中的b被赋值为1,a被赋值为2,以此类推。不知道我的解释是否正确,还请各位大佬不吝赐教。
发表于 2019-08-29 12:38:47 回复(4)