Codeforces Round 886 (Div. 4) 全题题解

我关注的人中正式参与比赛排名公示

# Who = Penalty * A B C D E F G H
1 (980) China Chen_Jinhui 7 381 \(\color{#00CC00}{\textbf{+}}\) 00:05 \(\color{#00CC00}{\textbf{+1}}\) 00:17 \(\color{#00CC00}{\textbf{+}}\) 00:19 \(\color{#00CC00}{\textbf{+}}\) 01:08 \(\color{#00CC00}{\textbf{+}}\) 00:55 \(\color{#00CC00}{\textbf{+}}\) 01:35 \(\color{#00CC00}{\textbf{+}}\) 01:52
2 (4685) China LQ1120241921 5 160 \(\color{#00CC00}{\textbf{+}}\) 00:04 \(\color{#00CC00}{\textbf{+}}\) 00:10 \(\color{#00CC00}{\textbf{+}}\) 00:18 \(\color{#00CC00}{\textbf{+}}\) 01:13 \(\color{#140c34}-2\) \(\color{#00CC00}{\textbf{+}}\) 00:55
3 (5657) China zdrj2025 5 199 \(\color{#00CC00}{\textbf{+}}\) 00:05 \(\color{#00CC00}{\textbf{+}}\) 00:14 \(\color{#00CC00}{\textbf{+}}\) 00:32 \(\color{#00CC00}{\textbf{+}}\) 00:53 \(\color{#00CC00}{\textbf{+1}}\) 01:25
4 (6367) China linzibolzb 5 253 \(\color{#00CC00}{\textbf{+}}\) 00:06 \(\color{#00CC00}{\textbf{+}}\) 00:16 \(\color{#00CC00}{\textbf{+}}\) 00:26 \(\color{#00CC00}{\textbf{+2}}\) 01:00 \(\color{#00CC00}{\textbf{+2}}\) 01:45 \(\color{#140c34}-1\) \(\color{#140c34}-1\)
5 (7679) wy2025 4 62 \(\color{#00CC00}{\textbf{+}}\) 00:06 \(\color{#00CC00}{\textbf{+}}\) 00:11 \(\color{#00CC00}{\textbf{+}}\) 00:18 \(\color{#00CC00}{\textbf{+}}\) 00:27
6 (9024) s_zeratu 4 92 \(\color{#00CC00}{\textbf{+}}\) 00:05 \(\color{#00CC00}{\textbf{+}}\) 00:18 \(\color{#00CC00}{\textbf{+}}\) 00:23 \(\color{#00CC00}{\textbf{+}}\) 00:46
7 (9186) China DCZISSB 4 96 \(\color{#00CC00}{\textbf{+}}\) 00:04 \(\color{#00CC00}{\textbf{+}}\) 00:11 \(\color{#00CC00}{\textbf{+}}\) 00:20 \(\color{#00CC00}{\textbf{+1}}\) 00:51 \(\color{#140c34}-2\)
8 (9484) China c20251917 4 103 \(\color{#00CC00}{\textbf{+}}\) 00:05 \(\color{#00CC00}{\textbf{+}}\) 00:21 \(\color{#00CC00}{\textbf{+}}\) 00:23 \(\color{#00CC00}{\textbf{+}}\) 00:54
9 (9529) China Ariasaka 4 104 \(\color{#00CC00}{\textbf{+}}\) 00:02 \(\color{#00CC00}{\textbf{+}}\) 00:08 \(\color{#00CC00}{\textbf{+}}\) 00:16 \(\color{#00CC00}{\textbf{+}}\) 01:18 \(\color{#140c34}-7\)
10 (11019) China Li_Feiy-i7i 4 141 \(\small\color{gray}{-2}\) \(\color{#00CC00}{\textbf{+}}\) 00:08 \(\color{#00CC00}{\textbf{+}}\) 00:25 \(\color{#00CC00}{\textbf{+}}\) 00:28 \(\color{#00CC00}{\textbf{+1}}\) 01:10 \(\color{#140c34}-2\)
11 (11710) China cyh1105 4 163 \(\color{#00CC00}{\textbf{+}}\) 00:04 \(\color{#00CC00}{\textbf{+}}\) 00:15 \(\color{#00CC00}{\textbf{+}}\) 01:01 \(\color{#00CC00}{\textbf{+}}\) 01:23
12 (11952) China dhaomin 4 172 \(\color{#00CC00}{\textbf{+}}\) 00:03 \(\color{#00CC00}{\textbf{+}}\) 00:36 \(\color{#00CC00}{\textbf{+}}\) 00:35 \(\color{#00CC00}{\textbf{+3}}\) 01:08
13 (14718) czyawa 3 57 \(\color{#00CC00}{\textbf{+}}\) 00:07 \(\color{#00CC00}{\textbf{+}}\) 00:21 \(\color{#00CC00}{\textbf{+}}\) 00:29
14 (18562) z_m_x 3 210 \(\color{#00CC00}{\textbf{+}}\) 01:45 \(\color{#00CC00}{\textbf{+}}\) 01:08 \(\color{#00CC00}{\textbf{+}}\) 00:37
15 (21815) iamchenzh 1 16 \(\color{#00CC00}{\textbf{+}}\) 00:16 \(\color{#140c34}-6\)
16 (21948) China 0930_songzhiyu 1 20 \(\color{#00CC00}{\textbf{+}}\) 00:20 \(\color{#140c34}-3\)
Accepted Tried \(\color{#00CC00}{\text 23198}\) 23269 \(\color{#00CC00}{\text 20370}\) 21272 \(\color{#00CC00}{\text 19959}\) 19987 \(\color{#00CC00}{\text 13233}\) 14229 \(\color{#00CC00}{\text 6535}\) 7658 \(\color{#00CC00}{\text 3335}\) 6428 \(\color{#00CC00}{\text 1330}\) 2226 \(\color{#00CC00}{\text 386}\) 876

题解部分

A - To My Critics

AI 会做的题你不会做?可以退役了。

直接贴代码,不予解释。

//the code is from chenjh
#include<cstdio>
void solve(){
	int a,b,c;scanf("%d%d%d",&a,&b,&c);
	puts(a+b>=10||a+c>=10||b+c>=10?"YES":"NO"); 
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve(); 
	return 0;
}

B - Ten Words of Wisdom

题意

\(n\) 对数 \(a,b\),需要你找到 \(a_i \le 10\)\(b_i\) 最大时的 \(i\) 是多少。

保证有解。

分析

直接对于每一个 \(i\) 判断即可,进行打擂台。

代码

//the code is from chenjh
#include<cstdio>
int n,a[55],b[55];
void solve(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
	int x=0;//答案。
	for(int i=1;i<=n;i++)if(a[i]<=10&&b[i]>b[x]) x=i;//ai<=10 且 bi 大于当前值,则更新答案。
	printf("%d\n",x);
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve(); 
	return 0;
}

洛谷博客:题解 CF1850B Ten Words of Wisdom

C - Word on the Paper

题意

给你一个 \(8 \times 8\) 的字符方阵,里面有一个竖着的由小写字母组成单词,除外都是 .,请你找出这个单词。

分析

输出 \(8 \times 8\) 矩阵的非 . 字符即可,读入一个字符,如果不为 .,那么就立刻输出。

最后记得输出换行。

注意事项

使用 getchar 读入时,一定要注意换行和空格一些不可见字符,否则可能会出现读入问题。

代码

//the code is from chenjh
#include<cstdio>
void solve(){
	for(int i=0;i<8;i++){
	    char ch;
		for(;~(ch=getchar()) && ch!='\n';);//读入换行空格。
		for(int j=0;j<8;j++) if((ch=getchar())!='.')putchar(ch);//如果不是 . 就输出该字符。
	}
	putchar('\n');//换行。
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve(); 
	return 0;
}

洛谷博客:题解 CF1850C Word on the Paper

D - Balanced Round

题意

给你一个有 \(n\) 个整数的序列 \(a\),求最多需要删除多少个数才能让任意两个问题的绝对值之差小于等于 \(k\)

分析

首先我们将序列 \(a\) 排序。

经过分析,如果 \(a_i-a_{i-1}>k\),那么 \(a_i\) 左侧的都会被删除。

经过观察可以发现,我们可以算出最多保留多少个。

个数即为相邻两个绝对值小于等于 \(k\) 的最大长度。

最后答案即为 \(n\) 减去最多保留个数。

代码

//the code is from chenjh
#include<cstdio>
#include<algorithm>
int n,k;
int a[200002];
void solve(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	std::sort(a+1,a+n+1);
	if(n==1){puts("0");return;}//特判 n=1 时一定为 0。
	int ans=0,c=1;//连续段数至少为 1。
	for(int i=2;i<=n;i++)
		ans=std::max(ans,c=((a[i]-a[i-1]<=k)?c:0)+1);//如果绝对值小于等于 k,那么加一,否则归为 1。
	printf("%d\n",n-ans);//即 n 减去最大长度。
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve(); 
	return 0;
}

洛谷博客:题解 CF1850D Balanced Round

E - Cardboard for Pictures

题意

给你 \(n\) 个整数 \(s\) 和一个整数 \(c\),你需要找到一个整数 \(w\) 满足 \(\sum\limits_{i=1}^n(2w+s_i)^2=c\)

分析

很显然这是一个一元二次方程。

将上式根据完全平方公式化简可以得到,我们要求的方程是:

\[4nw^2+(2\sum\limits_{i=1}^ns_i)w+\sum\limits_{i=1}^ns_i^2=c \]

移项又可以得到:

\[4nw^2+(2\sum\limits_{i=1}^ns_i)w+(\sum\limits_{i=1}^ns_i^2)-c=0 \]

所以直接用求根公式可以解得:

\[w=\dfrac{-2\sum\limits_{i=1}^ns_i+\sqrt{4(\sum\limits_{i=1}^ns_i)^2-16n\sum\limits_{i=1}^ns_i^2}}{8n} \]

注意事项

可能需要用到 __int128,需要使用 C++20,并且需要手写 sqrt 函数。(但是 long double 强转好像也可以过)。

代码

//the code is from chenjh
#include<cstdio>
typedef long long LL;
int n;LL c;
__int128 mySqrt(__int128 x){if(!x)return 0;__int128 left=1;__int128 right=x>>1;while(left<right){__int128 mid=(right+left)/2+1;if(mid>x/mid) right=mid-1;else left=mid;}return(__int128)left;}//手写二分 sqrt。
void solve(){
	scanf("%d%lld",&n,&c);
	LL A=(n<<2),B=0,C=0;//一元二次方程的三个系数。
	for(int i=1,s;i<=n;i++){
		scanf("%d",&s);
		B+=s,C+=s*s;
	}
	B<<=2ll;
	printf("%lld\n",LL((-B+mySqrt((__int128)B*B-(__int128)4*A*(C-c)))/2/A));//根据求根方程求解。
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve(); 
	return 0;
}

洛谷博客:题解 CF1850E Cardboard for Pictures

F - We Were Both Children

Update on 2023/7/23 18:52:经管理员 @CSP_Sept 提醒,修改整除符号表示。

题意

给定 \(n\) 个整数 \(a\),你需要找到一个整数 \(x \in [1,n]\) 使得 \(\sum\limits_{i=1}^n[a_i \mid x]\) 最大。

分析

这一道题根本就不需要筛因数!

其实只要你稍微优化一下暴力,这个是可以过的。

如果你不优化就会像我的同学一样被 Hack

我们可以用一个 std::map 存储有多少只距离为 \(x\) 的青蛙。

设一个 \(b\) 数组表示 \(b_i\) 为青蛙会经过 \(i\) 这个位置的只数。

然后对于每一个 \(x\mid i\),只需要每一次加距离为 \(x\) 青蛙的只数就可以了,如果每一次遍历都只加一个会显得十分浪费。

还有一个小优化就是特判 \(a_i=1\),这种情况可以特殊处理,因为它对于每一个位置都是可行的,所以单独讨论。

最坏情况下,时间复杂度是 \(O(n\sum\limits_{i=1}^n\dfrac{1}{i}) \approx O(n \log n)\),使用 std::map 维护需要再乘一个 \(\log n\),所以总的时间复杂度为 \(O(n \log^2 n)\)

代码

//the code is from chenjh
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<utility>
int n,a[200002],b[200002];
std::map<int,int> M;
void solve(){
	M.clear();
	scanf("%d",&n);
	memset(b,0,sizeof(int)*(n+1));//清空数组,并不需要清空全部。
	int s=0;//为 1 的个数。
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(a[i]==1) ++s;//特判为 1 的情况。
		else if(a[i]<=n) ++M[a[i]];//如果大于 n 则不需要考虑。
	}
	for(std::pair<int,int> it:M){
		for(int i=it.first;i<=n;i+=it.first) b[i]+=it.second;//暴力加答案。
	}
	int ans=s;
	for(int i=1;i<=n;i++)ans=std::max(ans,b[i]+s);//当前位置加一的个数即为当前答案,然后取最大值。
	printf("%d\n",ans);
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve();
	return 0;
}

洛谷博客:题解 CF1850F We Were Both Children

G - The Morning Star

题意

给你 \(n\) 个点的坐标,你需要找出有多少组不重合的点满足一个点在另一个点的正北、正南、正东、正西、西北、东北、西南、东南方向。

分析

只需要记录每一行、每一列、每一条斜线上有多少个点即可。

设当前行、列、斜线上有 \(x\) 个点,那么答案就为 \(x(x-1)\)

问题在于如何记录,对于行列,我使用了 std::map,斜线就可以用一个 std::pair<int,int> 记录函数解析式。

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

代码

//the code is from chenjh
#include<cstdio>
#include<map>
#include<utility>
typedef long long LL;
typedef std::pair<int,int> PII;
int n;
std::map<int,int> H,L;
std::map<PII,int> M;
void solve(){
	scanf("%d",&n);
	H.clear(),L.clear();
	M.clear();
	for(int i=1,x,y;i<=n;i++){
		scanf("%d%d",&x,&y);
		++H[x],++L[y];//记录行、列。
		++M[{1,-x+y}],++M[{-1,x+y}];//上升的函数(k=1)和下降的函数(k=-1)。
	}
	LL ans=0;
	for(PII x:H) ans+=(LL)x.second*(x.second-1);//依次统计答案。
	for(PII x:L) ans+=(LL)x.second*(x.second-1);
	for(std::pair<PII,int> x:M) ans+=(LL)x.second*(x.second-1);
	printf("%lld\n",ans);
}
int main(){
	int T;scanf("%d",&T);
	while(T--) solve();
	return 0;
}

洛谷博客:题解 CF1850G The Morning Star

H - The Third Letter

详细请见 Tutorial (en)

posted @ 2023-07-23 20:15  Chen_Jinhui  阅读(155)  评论(0)    收藏  举报