Educational Codeforces Round 131 div.2 A-F题解
Posted 欣君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 131 div.2 A-F题解相关的知识,希望对你有一定的参考价值。
视频讲解:BV1bU4y1q7CB
A. Grass Field
题目大意
给定 2 × 2 2\\times 2 2×2 的01矩阵,每次操作可以将一行和一列的 1 1 1 变成 0 0 0 ,求最少需要几次操作,得到全零矩阵。
题解
简单模拟。
如果总和为
4
4
4 则需
2
2
2 次。
如果总和为
0
0
0 则需
0
0
0 次。
其余为
1
1
1 次。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
int T,a,b,c,d,sum;
scanf("%d",&T);
while(T--)
scanf("%d%d%d%d",&a,&b,&c,&d);
sum=a+b+c+d;
if(sum==4)
puts("2");
else if(sum==0)
puts("0");
else
puts("1");
B. Permutation
题目大意
对于排列 p p p 和给定正整数 d d d ,定义排列 p p p 的费用为满足 p i ⋅ d = p i + 1 p_i\\cdot d=p_i+1 pi⋅d=pi+1 的 i ( 1 ≤ i < n ) i(1 \\leq i <n) i(1≤i<n) 的数量。
现在给定 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n(2 \\leq n \\leq 2 \\cdot 10^5) n(2≤n≤2⋅105) ,求出一组费用最大的正整数 d d d 和排列 p p p 。
题解
首先可以想到,最优的
d
d
d 为
2
2
2 。
当
n
=
6
n=6
n=6 时,一组最优解为
1 2 4 3 6 5
因此从小到大枚举,对于未出现过的数,逐个输出其 2 2 2 倍即可。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=200200;
int vis[MAXN];
int main()
int T,n,i,j;
scanf("%d",&T);
while(T--)
scanf("%d",&n);
memset(vis,0,sizeof(vis));
puts("2");
for(i=1;i<=n;i++)
for(j=i;j<=n&&!vis[j];j*=2)
printf("%d ",j);
vis[j]=1;
puts("");
C. Schedule Management
题目大意
给定 n n n 个工人和 m m m 个任务。第 i i i 个任务如果由 a i a_i ai 号工人完成,消耗 1 1 1 小时吗,其他工人完成消耗 2 2 2 小时。
所有工人同时并行独立开始工作,每名工人同时只能完成一个工作。
求所有任务完成的最少消耗时间。
题解
直接二分答案。
注意开long long。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=200200;
int n,m;
int num[MAXN];
bool judge(int limit)
ll undo=0;
for(int i=1;i<=n;i++)
if(num[i]<=limit)
undo-=(limit-num[i])/2;
else
undo+=num[i]-limit;
return undo<=0;
int main()
int T,x,i,lef,rig,mid;
scanf("%d",&T);
while(T--)
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
num[i]=0;
for(i=1;i<=m;i++)
scanf("%d",&x);
num[x]++;
lef=0;rig=2*m;
while(lef<=rig)
mid=(lef+rig)/2;
if(judge(mid))
rig=mid-1;
else
lef=mid+1;
printf("%d\\n",lef);
D. Permutation Restoration
题目大意
数组
b
b
b 由排列
a
a
a 通过
b
i
=
⌊
i
a
i
⌋
b_i=\\lfloor \\fracia_i \\rfloor
bi=⌊aii⌋ 得到。
给定长度为
n
(
1
≤
n
≤
5
⋅
1
0
5
)
n(1 \\leq n \\leq 5 \\cdot 10^5)
n(1≤n≤5⋅105) 的
b
b
b ,求出任意一个合法的
a
a
a 排列。
题解
由
b
i
=
⌊
i
a
i
⌋
b_i=\\lfloor \\fracia_i \\rfloor
bi=⌊aii⌋ 可得
a
i
b
i
≤
i
≤
a
i
(
b
i
+
1
)
−
1
a_i b_i \\leq i \\leq a_i(b_i+1)-1
aibi≤i≤ai(bi+1)−1
当
b
i
=
0
b_i=0
bi=0 时
a
i
≥
⌈
i
+
1
b
i
+
1
⌉
=
⌊
i
+
b
i
+
1
b
i
+
1
⌋
a_i\\geq \\lceil \\fraci+1b_i+1 \\rceil=\\lfloor \\fraci+b_i+1b_i+1 \\rfloor
ai≥⌈bi+1i+1⌉=⌊bi+1i+bi+1⌋
当
b
i
≠
0
b_i \\neq 0
bi=0 时
⌊
i
+
b
i
+
1
b
i
+
1
⌋
≤
a
i
≤
⌊
i
b
i
⌋
\\lfloor \\fraci+b_i+1b_i+1 \\rfloor \\leq a_i \\leq \\lfloor \\fracib_i \\rfloor
⌊bi+1i+bi+1⌋≤ai≤⌊bii⌋
由此,对于排列
a
a
a 上的每个位置,选择一个区间内的数填充。这是经典的贪心问题。
将所有区间按右端点排序,对于每个区间,选择区间内未被选中过的最小的数,填充到对应位置上。
选择区间内未被选中过的最小的数,可以采用set+lower_bound实现。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=500500;
int a[MAXN];
set<int> stEducational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33