11.27 NOIP模拟赛题解

T1 Voting (Hard Version) CF1251E2


原题链接

为什么要贿赂选民给你投票!!!

题意:

主角需要获得 n n n个人的投票
有两种方式让某个人给他投票

  1. 已经投票的人数 > m >m >m
  2. p p p枚硬币购买
分析:

m m m进行排序

保留前缀的 m m m数组, p r e [ x ] pre[x] pre[x] m m m小于等于 x x x的人数

x x x进行逆序处理,当枚举到 x x x的时候,假设 m m m小于等于 x − 1 x-1 x1的那些人已经投票,也就是有 p r e [ x − 1 ] pre[x-1] pre[x1]人已经投票

如果 p r e [ x − 1 ] ≥ x pre[x-1] \ge x pre[x1]x那么不需要进行处理

如果 p r e [ x − 1 ] < x pre[x-1]<x pre[x1]<x那么 m m m x x x n n n的人至少要收买 x − p r e [ x − 1 ] x-pre[x-1] xpre[x1]个人

得到所有 x x x需要收买的后缀,显然从后往前处理最优。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 7;
int pre[N];
vector<int>q[N];
multiset<int>se;//元素可重复且元素有序
int main() {
   
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
   
		int a, b;
		scanf("%d %d", &a, &b);
		pre[a]++;
		q[a].push_back(b);
	}
	for (int i = 1; i <= n; i++)
		pre[i] += pre[i - 1];
	int cnt = 0;
	ll ans = 0;
	for (int i = n; i >= 1; i--) {
   
		int len=q[i].size();
		for (int j = 0; j < len; j++){
   
			se.insert(q[i][j]);
		}
		int v = i - cnt - pre[i - 1];
		while (v > 0) {
   
			ans += (*se.begin());
			se.erase(se.begin());
			v--;
			cnt++;
		}
	}
	se.clear();
	for (int i = 0; i <= n; i++) {
   
		q[i].clear(), pre[i] = 0;
	}
	printf("%lld\n", ans);
	return 0;
}

懂王也是胜选了,四年河东,四年河西,莫欺老人穷

T2 P2397 yyy loves Maths VI (mode)


原题链接

一眼就能看出来是求众数,觉得很简单,但还是想了一会做法才切出来。

我们可以把所给数字分成两类:

一类是众数,一类是其他的数

根据题目所给条件,众数的数量一定严格大于其他数的数量。

如果我们使用每一个其他不同的数来抵消众数,那么抵消完毕之后,剩下的数一定全都是众数。

那么有了思路我们就来想想实现过程:

  1. 建一个变量 a n s ans ans存储当前找到的众数,建一个变量 c n t cnt cnt存储当前众数的数量
  2. 新加入一个数
  3. 如果和 a n s ans ans相同,即和当前找到的众数相同, c n t + + cnt++ cnt++
  4. 如果 c n t = 0 cnt=0 cnt=0,即没有找到众数,则把新数作为众数,即 a n s = ans= ans=新数, c n t = 1 cnt=1 cnt=1
  5. 如果不同,那么 c n t − − cnt-- cnt,即把当前的众数抵消掉一个
  6. 最后剩下来的 a n s ans ans就是众数

c o d e code code

#include<bits/stdc++.h>
using namespace std;
int n;
int ans,tot;//tot同cnt
int main()
{
   
	scanf("%d",&n);
	for
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值