首页 > 其他分享 >Educational Codeforces Round 172 (Rated for Div. 2) A ~ D

Educational Codeforces Round 172 (Rated for Div. 2) A ~ D

时间:2024-12-03 21:12:57浏览次数:6  
标签:Educational Rated int void ans Codeforces cin cnt 区间

Educational Codeforces Round 172 (Rated for Div. 2)
广告:starrycoding九折优惠码(FV7B04LL)

A

思路

  • 需要拿至少 \(k\) 枚硬币.
  • 从大到小拿.
  • 拿到的硬币最少.

题目没有要求补硬币的数目, 要求回答的是拿最少硬币时至少补多少.
而拿取的最小值最少为 \(k\).
求从大到小拿取到哪个箱子时, 再拿下一个箱子就超过 \(k\), 补足此时的硬币即可.

代码

void func(void)
{
	int n,k;
	cin >> n >> k;
	vector<int> a(n+1);
	for(int i=1;i<=n;++i)	cin >> a[i];
	sort(a.begin()+1,a.end(),greater<int>());
	int sum = 0;
	for(int i=1;i<=n;++i)
	{
		if(sum + a[i] > k)
		{
			cout << k - sum << '\n';
			return ;
		}
		sum += a[i];
	}
	cout << (k-sum > 0 ? k-sum : 0) << '\n';
}

B

思路

对于每种弹珠, 最多拿 \(2\) 分, 设此种弹珠总数 \(cnt\) 可以计算.

  • \(cnt = 1\)
    • \(2\) 分需要 \(1\) 次.
  • \(cnt > 1\)
    • \(1\) 分需要 \(1\) 次.
    • \(2\) 分需要 \(cnt > 1\) 次.

对于有 \(cnt > 1\) 的弹珠, A 拿取 \(1\) 个后, B 可以再拿 \(1\), 使得 A 无法拿到所有.
最佳策略为:
AB均抢占 \(cnt = 1\), 的弹珠, 然后 \(cnt > 1\) 的弹珠各拿一个.
总得分为 \(<cnt_1/2> + cnt_{>1}\)(\(<>\) 为向上取整, 因为奇数个时必然是 A 拿到).

代码

void func(void)
{
	int n;
	cin >> n;
	map<int,int> cnt;
	for(int i=0;i<n;++i)
	{
		int X;	cin >> X;
		cnt[X] ++;
	}
	int cnt1 = 0, cnt2 = 0;
	for(auto &i : cnt)
	{
		if(i.y == 1)	cnt1 ++;
		else	cnt2 ++;
	}
	cout << ((cnt1+1)/2 * 2 + cnt2) << '\n';
}

C

思路

对于字符串的 \(01\), \(1\) 可视为抵消 \(0\), 那么将 \(0\) 视为 \(-1\).

  • 假设起始只有 \(1\) 个区间.
  • 每次增加区间, 就是分割了某个区间.

每次分割操作会使得分割点之右的点贡献 \(+1\).
那么只需要每次贪心贡献最大的分割点, 当总贡献 \(\ge k\) 时输出分割次数即可.

因为每次分割点的贡献是其右侧的贡献之和, 所以使用 后缀和.
将所有后缀和加入一个 大根堆, 每次取出最大的 后缀和, 即分割此处.
大根堆使用 stl 的priority_queue.

代码

void func(void)
{
	int n,k;
	cin >> n >> k;
	string st;
	cin >> st;
	st = '0' + st;
	vector<int> s(n+2);
	priority_queue<int> pq;
	for(int i=n;i>=2;--i)
	{
		s[i] = s[i+1] + (st[i] == '0' ? -1 : 1);
		pq.push(s[i]);
	}
	int ans = 1, sum = 0;
	while(pq.size())
	{
		int X = pq.top();	pq.pop();
		sum += X;
		ans ++;
		if(sum >= k)
		{
			cout << ans << '\n';
			return ;
		}
	}
	cout << -1 << '\n';
}

D

思路

题意: 用户\(j\)有一个偏好区间\((L_j,R_j)\). 他需要找到另一些用户\(i\), 他们的区间\((L_i,R_i)\)包含该用户的区间(\(L_i \le L_j \le R_j \le R_i\)). 然后用户\(i\) 们会找到他们区间的共同部分, 将其中 \(j\) 没有的部分推荐给 \(j\). 每次需要回答推荐的次数. 若是 \(i\) 不存在或者不存在推荐部分, 则输出 \(0\).

因为 \(n \le 10^5\), 所以对每个元素的操作应该为 \(logn\).

分析题面后, 我们实际上需要求包含 \(j\) 的区间的最大 \(L\) 和 最小 \(R\).

我们可以分别处理.

\(L\):
先根据区间的 \(R\) 从大到小排序(\(R\) 相同时根据 \(L\)从小到大排, 保证大区间先加入, 小区间可以被包含), 将区间顺序(实际加入的是 \(L\))加入一个容器.

  • 先加入的元素 \(R\) 一定大于后加入的元素的 \(R\).
  • 那么后加入的元素不可能包含先加入的

然后判断当前容器中有没有小于等于 \(L_j\) 的, 最大的值即为该 \(j\) 的 \(ans_L\)

\(R\):
同理, 按区间 \(L\) 从小到大排序.

  • 后加入的元素不可能包含先加入的

然后判断当前容器中有没有大于等于 \(R_j\) 的, 最小的值即为 \(j\) 的 \(ans_j\).

注意:

  • 如果有完全相同的区间, 若是代码有漏网之鱼, 需要将其单独处理掉.
  • 排序后的插入, 保证先插入大区间, 小区间可以被大区间包含.

因为对于每个元素查找 \(ans_L, ans_R\)需要 \(log\)级别, 所以需要用 二分查找.
set 的插入也只是 \(log\), 且自动排序支持二分 所以上述的容器可以使用 set.

代码

#include<bits/stdc++.h>
#define Start cin.tie(0), cout.tie(0), ios::sync_with_stdio(false)
#define PII pair<int,int> 
#define x first
#define y second
#define ull unsigned long long
#define ll long long
using namespace std;

struct sth
{
	int x,y,z;
	bool operator < (const sth &i)	const
	{
		return(z == i.z ? (y == i.y ? x < i.x : y < i.y) : z < i.z);
	}
};

const int M = 1000000007;
const int N = 2e5 + 10;

bool cmp1(sth a,sth b)
{
	return (a.y == b.y ? a.x < b.x : a.y > b.y);
}

bool cmp2(sth a,sth b)
{
	return (a.x == b.x ? a.y > b.y : a.x < b.x);
}

void func(void);

signed main(void)
{
	Start;
	int _ = 1;
	cin >> _;
	while(_--)	func();
	return 0;
}

void func(void)
{
	int n;
	cin >> n;
	vector<sth> a(n+1);
	vector<PII> ans(n+1,{-1,-1});
	map<PII,vector<int>> check;// 处理完全重复的结果
	for(int i=1;i<=n;++i)
	{
		cin >> a[i].x >> a[i].y;
		a[i].z = i;
		check[{a[i].x,a[i].y}].push_back(i);
	}
	set<int,greater<int>> s1;
	sort(a.begin()+1,a.end(),cmp1);// 第一次排序
	for(int i=1;i<=n;++i)
	{
		auto X = s1.lower_bound(a[i].x);
		if(X != s1.end())	ans[a[i].z].x = *X;
		s1.insert(a[i].x);
	}
	set<int> s2;
	sort(a.begin()+1,a.end(),cmp2);// 第二次排序
	for(int i=1;i<=n;++i)
	{
		auto X = s2.lower_bound(a[i].y);
		if(X != s2.end())	ans[a[i].z].y = *X;
		s2.insert(a[i].y);
	}
	sort(a.begin()+1,a.end());// 恢复区间, 按顺序输出
	for(auto &i : check)
	{
		if(i.y.size() > 1)
		{
			for(auto &j : i.y)	ans[j] = {-1,-1};// 处理重复区间
		}
	}
	for(int i=1;i<=n;++i)
	{
		int X = (ans[i].y - ans[i].x - (a[i].y - a[i].x));
		if(ans[i].x == -1 || ans[i].y == -1 || X < 0)	cout << 0 << '\n';
		else	cout << X << '\n';
	}
}

标签:Educational,Rated,int,void,ans,Codeforces,cin,cnt,区间
From: https://www.cnblogs.com/zerocloud01/p/18585051

相关文章

  • Educational Codeforces Round 172 (Rated for Div. 2) D. Recommendations
    算法听别人说这题比较简单,我来看看怎么个事转化题意,对于\(n\)条线段\([l_i,r_i]\),求每条线段被哪些线段完全覆盖,并求这些线段的交集减去其的长度显然的,\(j\)线段覆盖\(i\)线段,应该满足\(l_j\leql_i,r_i\leqr_j\)那么我们考虑将每一条线段当做一个点......
  • VMware Integrated OpenStack 7.3 现已支持 vSphere 8.0U3 和 NSX 4.2 互操作性
    VMwareIntegratedOpenStack7.3-VMware支持的OpenStack发行版VMware支持的OpenStack发行版:在VMware虚拟化技术之上运行企业级OpenStack云请访问原文链接:https://sysin.org/blog/vmware-vio-7/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgVMwareIn......
  • 【双堆懒删除】codeforces 1294 D. MEX maximizing
    前言双堆懒删除当需要维护若干元素中的最大值(或最小值)时,可以用一个堆维护,但是堆只擅长处理堆顶元素,对堆中任意元素的处理就束手无策了。此时,可以引入另外一个堆,我们定义原来的堆为保存堆\(ex\),新的堆为懒删除堆\(de\)。那么当需要从保存堆中删除任意一个元素时,可以先将元素放......
  • Educational Codeforces Round 169 (Rated for Div2)
    EducationalCodeforcesRound169(RatedforDiv.2)-CodeforcesProblem-A-Codeforces构造签到题,明显只有\(n\leq2\)的时候有解#include<bits/stdc++.h>usingnamespacestd;constintN=2e5+10;typedefpair<int,int>pii;intn,m;inta[N];voidsolve(......
  • Educational Codeforces Round 171 (Rated for Div
    EducationalCodeforcesRound171(RatedforDiv.2)-CodeforcesProblem-A-Codeforces几何构造没什么好说的,\(45\)度交的时候长度最大#include<bits/stdc++.h>usingnamespacestd;constintN=3e5+10;voidsolve(){ intx,y,k;cin>>x>>y>>k; if(x......
  • E. Photoshoot for Gorillas(Codeforces Round 966 (Div. 3))
    https://codeforces.com/contest/2000/problem/E题目描述你非常喜欢屮大猩猩,于是你决定为它们组织一次拍摄活动。大猩猩生活在丛林中,丛林被表示为一个有n行m列的网格,有w个大猩猩同意参与拍摄,第i个大猩猩的身高ai.你希望将所有大猩猩放置在网格的单元格中,并且确保每个单......
  • 每日一题:https://codeforces.com/contest/1700/problem/B
    题目链接:https://codeforces.com/contest/1700/problem/B#include<iostream>#include<string.h>#include<string>#include<cmath>#include<algorithm>usingnamespacestd;intmain(){intu;cin>>u;for(inti=1;i......
  • Codeforces Round 987 (Div. 2)
    目录写在前面A签到B结论,枚举C构造,数学D枚举,数据结构Edfs,树形DP,构造写在最后写在前面比赛地址:https://codeforces.com/contest/2031退役?累了。妈的明天体测测完直接飞昆明感觉要爆了、、、A签到保证给定序列不升,要求修改到不降,则将所有元素修改至相等一定是不劣的。......
  • 【二分+前缀和+后缀和】codeforces 2026 D. Sums of Segments
    题目https://codeforces.com/problemset/problem/2026/D题意第一行输入一个正整数\(n(1\leqn\leq3e5)\),第二行输入\(n\)个整数\(a_1,a_2,...,a_i,...,a_n(-10\leqa_i\leq10)\),第三行输入一个正整数\(q(1\leqq\leq3e5)\),随后\(q\)行,每行输入两个整数\(......
  • CodeTON Round 9 (Div. 1 + Div. 2, Rated, Prizes!)(A~C2)
    A-ShohagLovesMod思路假设构造差值是\(x=0,1,\dots,n\)这样的,那么只要让\(a_i\equivx\pmod{i}\)即可,也就是\(a_i=i+x\)。代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;voidsolve(){intn;cin>>n;fo......