2021.01.19 模拟赛错题(1)

贪心

1.零件分组问题。
其实这道题和美元汇率我记得很清楚是网课的时候老师讲的,大家还一起讨论了,最后我也写了本题。但是,写了跟没写一样就很奇怪,一点印象都没,思路我明白,但卡住的点和我之前写的时候卡住的是一样的,但我却忘了之前是怎么解决的,淦。这怎么说,好像只能归结我没用心。但我还是自己动脑亲手写的,奇怪。
AC代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
	int l, w;
};
node v[10005];//结构体。用这么多次,终于熟练一点了。
bool cmp(node x, node y){
	if (x.l != y.l)return x.l < y.l;
	return x.w < y.w;//这个比较原理其实还是有点不懂。
}
int main(){
	int n, xn,yn;//xn为x大小,yn同上。
	int res = 0;//答案。
	int x[10005] = {}, y[10005] = {};
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%d %d", &v[i].l, &v[i].w);
	}
	sort(v + 1, v + 1 + n, cmp);//按长度先排序
	for(int i = 1; i <= n; i ++) x[++xn] = v[i].w;//把重量都赋到x数组里
	while(xn > 0){//只要数组里还有数,就要继续循环。
		int maxn = 0;
		yn = 0;
		for(int i = 1; i <= xn; i ++){
			if(x[i] >= maxn)maxn = x[i];//更新最大值
			else y[++yn] = x[i];//新开队列
		}
		res ++;//每循环完一次,就有一个队列。
		xn = yn;//使x大小变为剩下数的个数
		for(int i = 1; i <= xn; i ++)x[i] = y[i];//把新开数组里的数赋给x数组里,接着重复操作。
	}
	printf("%d", res);
	/*for(int i = 1; i <= n; i ++){
		for(int j = 1; j <= n; j ++){
			if(v[j].w != 0 && v[j].w >= max[i]){
				max[i] = v[j].w;
				v[j].w = 0;
			}
			if(v[j].w != 0 && v[j].w < max[i]){
				max[i + 1] = v[j].w;
				v[j].w = 0;
			}
		}
	}注释掉的这部分是我自己写的维护队列。然后计算总队列数。
	大意就是如果重量大于最大值,则替换掉最大值,这个数删掉。
	因为可以存在队列里。
	如果小于的话就新开一个队列,最大值存入,这个数删掉。
	最后计算有数的数组有几个。
	刚刚说到这儿我突然发现这个部分我写的一个问题,
	那就是没给max[1]赋初值!
	不过也不知道赋了会不会好使,总之先说过掉考试的ac代码吧。
	for(int i = 1; i <= n; i ++){
		if(max[i] != 0)c ++;
	}*/
	return 0;
	
}

这道题的收获:比较的写法。虽然原理还是不是太明白。

2.合并果子
明白思路,不会写,请教了学神,借此也学到不少新东西!!
上AC代码!耶!

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue>
using namespace std;
int main()
{
	priority_queue<int,vector<int>,greater<int> >q;
	/*
	没错!这就是新东西啦!优先队列!写法如上,最后的q是队列的名字。
	greater 可换成 less,此时存储顺序变为由大到小。
	用这个时需要引用几个库,那就是后加的仨。
	优先队列有几种用法:
	q.push():将元素压入队列。
	q.top():将元素放进去,元素成为第一个。
	q.pop():将第一个元素踢出队列。
	q.empty():判断队列是否为空。若为空则输出1,反之输出0;
	q.size():判断队列有几个元素。
*/
	int n, ans = 0;
	int a[10005] = {};
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++){
		scanf("%d", &a[i]);
		q.push(a[i]);
	}
	sort(a + 1, a + 1 + n);
	while(q.size()>=2){
		int x = q.top();
		q.pop();
		int y = q.top();
		q.pop();//这两个操作是为了把两个堆合并到一起。
		ans += x + y;
		q.push(x + y);
	}
	printf("%d", ans);
}

收获:学习了优先队列!
(其实刚刚回顾代码的时候发现还是有点点不懂while里的操作)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值