题目描述
Jakon家里有一堆未整理的书籍,胡乱地摆在书架上。有一天,身为强迫症的他终于看不下去了,于是他决定整理这堆图书,使其变得整齐一些。
他有n本高度、厚度、宽度确定的书籍,他决定按照高度、厚度、宽度分别作为第一、第二、第三关键字,把这些书籍降序地排列成一排。
输入
第一行:一个整数n,表示书籍的数量。(1≤n≤2×10^5)
接下来n行:每行三个整数h,s,w,分别表示某本书籍的高度、厚度、宽度。(1≤h,s,w≤10^9)
输出
共n行,根据题意将所有书籍进行排序后,按照顺序,每行输出一本书籍的高度、厚度、宽度。
样例输入
5
3 5 7
3 5 5
5 5 5
3 6 7
10 10 10
样例输出
10 10 10
5 5 5
3 6 7
3 5 7
3 5 5
提示
请使用O(nlogn)的算法。
这道题涉及到运算符重载以及排序。
第一种方法
注意:sort函数可以用于不同的容器(如vector、array)或数组,而不仅仅是普通的C-style数组。它使用迭代器来访问容器或数组的元素,并根据元素类型的小于操作符(<)进行排序。所以我们要对<操作符进行重载。这里重载之后返回的是左操作数<右操作数,是从小到大排序,题目要求从大到小排序,因此最后还要用reverse()翻转一下数组。
bool operator < (const book &u)const
{
if(h==u.h && s==u.s)
{
return w<u.w;
}
if(h==u.h)
{
return s<u.s;
}
return h<u.h;
}
第一个const是对u进行定义的,不去改变u的值,第二个const关键字位于函数声明的尾部,表示该成员函数是一个常量成员函数,常量成员函数承诺不会修改对象的状态,即在函数内部不能修改成员变量
示例代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+9; //2x10的5次方
struct book
{
int h;
int s;
int w;
bool operator < (const book &u)const
{
if(h==u.h && s==u.s)
{
return w<u.w;
}
if(h==u.h)
{
return s<u.s;
}
return h<u.h;
}
}p[N];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin >> p[i].h >> p[i].s >> p[i].w;
}
sort(p,p+n);
reverse(p,p+n); //翻转数组
for(int i=0;i<n;i++)
{
cout<<p[i].h<<" "<<p[i].s<<" "<<p[i].w<<'\n';
}
return 0;
}
通过:
第二种方法
其实与第一种方法差不多,只不过把重载<运算符时返回的参数换个位置,因为我们第一种方法调用<运算符时,如果是a<b,那么返回也是a<b(从小到大进行排序)。
而题目要求我们按从大到小进行排序,那么我们在重载运算符时直接把它也实现,就不用再去用reverse()函数翻转数组了,我们直接让它返回a>b,这样直接就实现了从大到小排序,会发现这种方法更简洁,效果更好。
bool operator < (const book&u) const
{
if(u.h==h&&u.s==s)
{
return u.w<w;
}
if(u.h==h)
{
return u.s<s;
}
return u.h<h;
}
示例代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+9;
struct book
{
int h,s,w;
bool operator < (const book&u) const
{
if(u.h==h&&u.s==s)
{
return u.w<w;
}
if(u.h==h)
{
return u.s<s;
}
return u.h<h;
}
}p[N];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>p[i].h>>p[i].s>>p[i].w;
}
sort(p,p+n);
for(int i=0;i<n;i++)
{
cout<<p[i].h<<" "<<p[i].s<<" "<<p[i].w<<'\n';
}
return 0;
}
通过:
两种方法的不同
两个比较操作符的不同会导致不同的排序结果。
return u.h < h;:这个表达式比较了参数对象 u 的高度 (u.h) 是否小于当前对象的高度 (h)。换句话说,它检查参数对象的高度是否小于当前对象的高度。
return h < u.h;:这个表达式比较了当前对象的高度 (h) 是否小于参数对象 u 的高度 (u.h)。换句话说,它检查当前对象的高度是否小于参数对象的高度。
若使用 return u.h < h;,表示按照高度从大到小进行排序。也就是说,高度较大的 book 对象会排在前面。
若使用 return h < u.h;,表示按照高度从小到大进行排序。也就是说,高度较小的 book 对象会排在前面。