【模板】排序(2)

题目描述

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 对象会排在前面。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值