Codeforces 杂题集

本文主要把近期 \(CF-Div.2\)\(A,B,C,D\) 题进行做

Round 815

A

题意

给你两个分数 \(\frac{a}{b},\frac{c}{d}\) ,问你最少几次使两个分数相等。

Solution

首先考虑,最大的情况为 \(2\) ,(两个分子都 \(\times 0\) 不就相等了),如果输入的分数相等,答案就是 \(0\) ,否则就不可能是 \(0\)

让我们假设,为了使分数在 \(1\) 次操作中相等,我们必须将第一个数的分数乘以 \(x\)。那么 \(\frac{ax}{b}=\frac{c}{d} \Rightarrow x=\frac{bc}{ad}\),检验一下能被整除即可。

if (x == y)
  cout << "0\n";
else if (y != 0 && x % y == 0 || x != 0 && y % x == 0)
  cout << "1\n";
else
  cout << "2\n";

B

题意

给你一个数列 \(a_n\) ,选一个 \(l,r\) ,使得下式最大化:

\[\max(a_1,a_2,…,a_{l−1},a_{r+1},a_{r+2},…,a_{n})−\min(a_1,a_2,…,a_{l−1},a_{r+1},a_{r+2},…,a_{n})+\max(a_l,…,a_r)−\min(a_l,…,a_r) \]

Solution

显然,答案不超过 \(max_1+max_2-min_1-min_2\) ,其中 \(max_1,max_2\) 是数组中两个最大值, \(min_1,min_2\) 是两个最小值。

那么答案就是这个。

时间复杂度 \(O(n)\) 或者 \(O(n \log n)\)

C

题意

有一个由 \(0\)\(1\) 组成的矩阵。

每次操作可以选择一个 \(2\times 2\) 的子矩阵,在这个子矩阵中选择一个 L 形,将这个 L 形里的 \(3\) 个数变成 0 ,注意,这个 L 形至少含有一个 \(1\) ,你想最大化操作个数,问最多操作多少次。

Solution

由于可能初始矩阵中没有一个位置可以做到一次操作仅消除一个 \(1\) ,所以我们要找到消除 \(1\) 数量最小的第一次操作,从第二次操作开始就可以做到每次消除一个 \(1\) 。先统计矩阵中 \(1\) 的个数,记为 \(sum\) ,若为 \(0\) ,则无法操作,输出 \(0\) 。否则枚举每个位置,并统计以这个位置为每一种形状的 L 形的角时,L 形内 \(1\) 的个数,只要这个个数大于 \(0\)(因为每次操作的 \(L\) 形中至少一个 \(1\) ),就将其比较并更新变量 \(Min\) 。最后 \(Min\) 就是最佳的第一次操作所消除的 \(1\) 的个数。答案即为 \(sum-Min+1\)

其实只要 check 一下有没有横着或者竖着的连着的两个 0 如果有,\(Min = 1\) ,若没有,\(Min = 2\) .

D

题意

Solution

for (int j = 1; j <= n; j++){
	dp[j] = 0;
	for (int k = max(j - M, 1); k < j; k++){
         	if ((a[j] ^ (k - 1)) > (a[k] ^ (j - 1))) dp[j] = max(dp[j], dp[k]);
	}
	ans = max(ans, ++dp[j]);
}

Round 814

Round 813

Round 812

Educational Round 133

Round 810

Round 809

Round 808

Round 807

Educational Round 131

Round 804

posted @ 2022-08-20 07:28  xlqs23  阅读(21)  评论(0编辑  收藏  举报