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 pid=pi+1 i ( 1 ≤ i < n ) i(1 \\leq i <n) i(1i<n) 的数量。

现在给定 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n(2 \\leq n \\leq 2 \\cdot 10^5) n(2n2105) ,求出一组费用最大的正整数 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(1n5105) 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 aibiiai(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 aibi+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+1aibii

由此,对于排列 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

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27