多元素排序

题目链接


唉,又是一道水题。

……每次花了一晚上\下午辛辛苦苦做完一题,总是看到一大堆的大神如此感叹到。由此更可以看出人与人之间的距离了。虽然很不愉快,很心酸看到这样的感叹,看到自己的千山万水竟是别人的谬之毫米。

……好想把心情写下去。不过怎么说,这是一篇讲题目的博客。如果有心情,再重新去写一篇吧!回归整体讲讲个人这题的经验。

题目要求输入长度l,重量w。并且求最短时间(详细题意,应该不用讲了吧?我英语很差的都看懂了说)

很显然这题要排序,而且是多元素排序,即可以先排序l,然后如果l是相等的元素,那么再根据w排序。比如说输入4 9 5 2 2 1 3 5 1 4排序完就是输出1 4 2 1 3 5 4 9 5 2了。

应为题目的意思是说,如果后面的比前面的大那么就不用时间了,所以,这里有一个陷阱,也是我毫不犹豫的踩进去的。即认为s[i+1].l<s[i].l || s[i+1].w<s[i].w就是必须给时间加1的(因为后面的元素存在比前面的小了),一开始这样想过去确实挺有道理的。可是看完答案就傻眼了吧。比如第一组输入数据你这样的话答案应该是3,而正确答案是2.

显然,这是思维的误区。至于哪里错呢?漏洞很多。

所以,我们应该排序没错。但是排序完要怎么做要参照题目的要求。具体的实现,请看如下代码中注释。

#include <iostream>
#include <algorithm>
using namespace std;
struct stick{
	int l; //长度
	int w;//重量
	bool flag; //判断是否访问过
};
bool cmp(const stick &s1, const stick &s2){ //升序排列
	if (s1.l != s2.l)//第一排列元素
		return (s1.l <= s2.l);
	else
		return (s1.w <= s2.w);//第二排列
}
int main()
{
	int T, n, res, i, j;
	stick s[5005], pre;
	cin >> T;
	while (T--){
		cin >> n;
		for (i = 0; i < n; i++){
			cin >> s[i].l >> s[i].w;
			s[i].flag = true;
		}
		sort(s, s + n, cmp);
			res = 0;
		for (i = 0; i < n; i++)
		{
		if (s[i].flag) //说明该结点还没有访问过(即W小于其前面一个)
		{
		s[i].flag = false;
		pre = s[i]; //设置从当前值往后寻找
		for (j = i + 1; j < n; j++){
		if (s[j].w >= pre.w&&s[j].flag == true)  //如果后面的大于前面一个说明满足条件时间不必加1
		{	s[j].flag = false; //该结点满足设置为false后面就不用再访问这个结点了
			pre = s[j];
		}
		}
		res++;
		}
		}
		cout << res << endl;
	}
	return 0;
}

总结:如果,你是和我一样的菜鸟。请记得,比你更牛逼的人,都已经把这题做完了,尽管他们略带轻蔑,可是他们还是那么一丝不苟的做完。所以,你凭什么逃避?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值