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(1≤n≤100) 个人,第 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+x≤hn+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(2≤n≤2⋅105) 个房间需要清理,第 i i i 个房间有 a i ( 0 ≤ a i ≤ 1 0 9 ) a_i(0 \\leq a_i \\leq 10^9) ai(0≤ai≤109) 件垃圾。每次操作包含以下步骤
- 选择一对 i , j i,j i,j ,满足 1 ≤ < j ≤ n 1 \\leq <j \\leq n 1≤<j≤n 且 a i , a i + 1 , . . . , a j − 1 a_i,a_i+1,...,a_j-1 ai,ai+1,...,aj−1 均严格大于 0 0 0 ;
- a i a_i ai 变为 a i − 1 a_i-1 ai−1
- 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=...=an−1=0 的最小操作数。
题解
对于
a
1
,
a
2
,
.
.
.
,
a
n
−
1
a_1,a_2,...,a_n-1
a1,a2,...,an−1 中的每一件垃圾,都需要花费
1
1
1 次操作清理。
左起第一个出现垃圾的房间到
a
n
−
1
a_n-1
an−1 ,每存在一个
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(1≤n≤2⋅105) 的字符串
s
s
s ,进行
c
(
1
≤
c
≤
40
)
c(1 \\leq c \\leq 40)
c(1≤c≤40) 次复制,每次复制选择区间
s
[
l
,
r
]
(
1
≤
l
≤
r
≤
1
0
18
)
s[l,r](1 \\leq l \\leq r \\leq 10^18)
s[l,r](1≤l≤r≤1018) ,复制并粘贴到字符串末尾。
有
q
(
1
≤
q
≤
1
0
4
)
q(1 \\leq q \\leq 10^4)
q(1≤q≤104) 次询问,每次询问求
s
k
(
1
≤
k
≤
1
0
18
)
s_k(1 \\leq k \\leq 10^18)
sk(1≤k≤1018) 。
题解
由于
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