Codeforces Round #807 (Div. 2) A-F题解

Posted 欣君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #807 (Div. 2) A-F题解相关的知识,希望对你有一定的参考价值。

视频讲解:BV1pG411p7Cd

A. Mark the Photographer

题目大意

给定 2 n ( 1 ≤ n ≤ 100 ) 2n (1 \\leq n\\leq 100) 2n(1n100) 个人,第 i i i 个人身高为 h i h_i hi 。将他们以任意顺序成两排,每排 n n n 人。问能否实现 ∀ i ∈ [ 1 , n ] \\forall i\\in [1,n] i[1,n] ,第二排的第 i i i 个人身高至少比第一排的第 i i i 个人高 x x x

题解

贪心。
n n n 个人从小到大排列,判断是否满足 ∀ i ∈ [ 1 , n ] , h i + x ≤ h n + i \\forall i\\in [1,n],h_i+x\\leq h_n+i i[1,n],hi+xhn+i 即可。
若存在 i = x i=x i=x 不满足条件,则 x x x 与更大或更小的元素交换位置,必定也不满足条件。若均满足条件,则得到一组合法解。

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN=220;
int a[MAXN];

int main()

	int T,n,x,i,flag;
	scanf("%d",&T);
	while(T--)
	
		scanf("%d%d",&n,&x);
		for(i=1;i<=2*n;i++)
			scanf("%d",&a[i]);
		sort(a+1,a+2*n+1);
		flag=1;
		for(i=1;i<=n;i++)
		
			if(a[i]+x>a[i+n])
				flag=0;
		
		if(flag)
			puts("YES");
		else
			puts("NO");
	

B. Mark the Dust Sweeper

题目大意

n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n(2 \\leq n \\leq 2 \\cdot 10^5) n(2n2105) 个房间需要清理,第 i i i 个房间有 a i ( 0 ≤ a i ≤ 1 0 9 ) a_i(0 \\leq a_i \\leq 10^9) ai(0ai109) 件垃圾。每次操作包含以下步骤

  • 选择一对 i , j i,j i,j ,满足 1 ≤ < j ≤ n 1 \\leq <j \\leq n 1≤<jn a i , a i + 1 , . . . , a j − 1 a_i,a_i+1,...,a_j-1 ai,ai+1,...,aj1 均严格大于 0 0 0
  • a i a_i ai 变为 a i − 1 a_i-1 ai1
  • a j a_j aj 变为 a j + 1 a_j+1 aj+1

求使得 a 1 = a 2 = . . . = a n − 1 = 0 a_1=a_2=...=a_n-1=0 a1=a2=...=an1=0 的最小操作数。

题解

对于 a 1 , a 2 , . . . , a n − 1 a_1,a_2,...,a_n-1 a1,a2,...,an1 中的每一件垃圾,都需要花费 1 1 1 次操作清理。
左起第一个出现垃圾的房间到 a n − 1 a_n-1 an1 ,每存在一个 a i = 0 a_i=0 ai=0 则需要额外操作 1 1 1 次。
以上两种操作数累加即可。
注意开long long。

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN=200200;
int a[MAXN];

int main()

	int T,n,i;
	ll ans;
	scanf("%d",&T);
	while(T--)
	
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		ans=0;
		for(i=1;i<n;i++)
		
			ans+=a[i];
			if(ans&&a[i]==0)
				ans++;
		
		printf("%lld\\n",ans);
	

C. Mark and His Unfinished Essay

题目大意

给定初始长为 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n(1 \\leq n \\leq 2 \\cdot 10^5) n(1n2105) 的字符串 s s s ,进行 c ( 1 ≤ c ≤ 40 ) c(1 \\leq c \\leq 40) c(1c40) 次复制,每次复制选择区间 s [ l , r ] ( 1 ≤ l ≤ r ≤ 1 0 18 ) s[l,r](1 \\leq l \\leq r \\leq 10^18) s[l,r](1lr1018) ,复制并粘贴到字符串末尾。
q ( 1 ≤ q ≤ 1 0 4 ) q(1 \\leq q \\leq 10^4) q(1q104) 次询问,每次询问求 s k ( 1 ≤ k ≤ 1 0 18 ) s_k(1 \\leq k \\leq 10^18) sk(1k1018)

题解

由于 c c c 不大,因此若 k > n k>n k>n 时,不断向前寻找当前的 k k k 来自于哪一次复制即可。
可以采用set+pair进行快速查找。
时间复杂度 O ( n + q c log ⁡ ( c ) ) O(n+qc\\log (c)) O(n+qclog(c))

参考代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN=200200;
char s[MAXN];
set<pair<ll,ll> > st;
set<pair<ll,ll> >::iterator it;

int main()

	int T,n,c,q;
	ll l,r,x,len;
	scanf("%d",&T);
	while(T--)
	
		scanf("%d%d%d",&n,&c,&q);
		scanf("%s",s+1);
		len=n;
		st.clear();
		while(c--)
		
			scanf("%lld%lld",&l,&r);
			st.insert(make_pair(len+1,l));
			len+=r-l+1;
		
		while(q--)
		
			scanf("%lld",&x);
			while(x>n)
			
				it=st.lower_bound(make_pair(x,1ll<<60));
				it--;
				x-=it->first-it->second;以上是关于Codeforces Round #807 (Div. 2) A-F题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #807 (Div. 2) A-F题解

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces 807C - Success Rate

AC日记——Success Rate codeforces 807c

AC日记——Dynamic Problem Scoring codeforces 807d