EDU-CFR-116-Div.2解题报告

比赛传送门

做出来五道题。

A. AB Balance

problem

给你一个只含有 a 和 b 的字符串,问怎样通过修改尽可能少的字符,使得 ab 的数量和 ba 的数量相等。

显然,ab 的数量和 ba 的数量最多差 11,而当开头字母和结尾字母相同时,ab 的数量等于 ba 的数量。如果不同,修改开头或结尾字母使它们相同即可。

B. Update Files

problem

有 nn 个电脑和 kk 个数据线,其中一个电脑上有一个文件,每次可以通过数据线将文件从一个电脑传到另一个电脑上,耗时 11 小时。问至少需要几个小时才能让所有电脑都有文件。

设当前有 xx 个电脑有文件:若 x<=kx<=k,则通过 xx 条数据线将 xx 翻倍;若 x>kx>k,则通过 kk 条数据线将 x+=kx+=k。暴力跑第一种情况(log⁡(k)\log(k)),剩下的情况算一下就行了。

C. Banknotes

problem

有 nn 中不同面值的货币,每种货币的面值为 10ai10^{a_i},问至少需要 x+1x+1 个货币才能组成的价值最小的货币是多少。

暴力贪心模拟。先尽可能多地用面值最小的货币,再用面值第二小的货币,以此类推。具体实现细节比较多,在这里放个代码。

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
using namespace std;
int n,k,a[10];
int main() {
int t;
cin>>t;
while(t--) {
cin>>n>>k;
k++;
for(int i=0;i<n;i++) {
cin>>a[i];
int cur=1;
while(x--)
cur*=10;
a[i]=cur;
}
long long res=0;
for(int i=0;i<n;i++) {
int cnt=k;
if(i<=n)
cnt=min(cnt,a[i+1]/a[i]-1);
res+=1ll*a[i]*cnt;
k-=cnt;
}
cout<<res<<endl;
}
}

D. Red-Blue Matrix

problem

有一个 n×mn\times m 的矩阵,每个格子有一个正整数,你需要对每一行染成红色或蓝色,使得能够找到竖线,让左边所有红格子都大于所有蓝格子的值,右边相反。输出染色方案以及竖线位置。

∑n×m≤106\sum n\times m\le 10^6

假设我们已经知道了竖线的位置,如何分配红蓝呢?考虑以行为单位,以每一行的第一个元素为关键字进行从大到小的排序,则我们发现,一定是上面几行为红色,下面几行为蓝色,而这个两条分界线,一横一竖,左上、右上为红,左下、右下为蓝,则必须满足左上的最小值大于左下的最大值,右上的最大值小于右下的最小值。我们可以对矩阵分别求从左上、右下开始的前缀最小值和从左下、右上开始的前缀最大值。枚举横、竖线,然后就可以 O(1)O(1) 判断了。总复杂度为 O(n×m)O(n\times m)。

E. Arena

待更新…