Codeforces Round #822 (Div. 2)

Preface

这场间隔有点久了,ABC是上周日打的,DE是这周四写的

感觉这场难度海星,比DE都不会的823友好多了


A. Select Three Sticks

容易发现最终变成的长度一定是已经存在的,因此排个序后枚举每个数让相邻的两个数变成它即可

#include<cstdio>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=305;
int t,n,a[N],ans;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d",&n),i=1;i<=n;++i) scanf("%d",&a[i]);
		for (ans=2e9,sort(a+1,a+n+1),i=2;i<n;++i) ans=min(ans,-a[i-1]+a[i+1]);
		printf("%d\n",ans);
	}
	return 0;
}

B. Bright, Nice, Brilliant

非常显然的构造题

不难发现对于第\(i\)层的边角房间,它们的明亮值最大就是\(i\),同时我们惊奇地发现如果不点亮其它房间的话这一层的其它房间的明亮值恰好也是\(i\)

因此对于每一层直接点亮左右的灯泡即可

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
int t,n;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; for (scanf("%d",&n),i=1;i<=n;++i)
		for (j=1;j<=i;++j) printf("%c%c",j==1||j==i?'1':'0'," \n"[j==i]);
	}
	return 0;
}

C. Removing Smallest Multiples

显然可以贪心地从小到大考虑每个\(k\),删除它所有的倍数

如果中途遇到不能删除的数就退出,不知道这题有什么难度

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=1000005;
int t,n,c[N]; char ch; long long ans;
inline void get_digit(char& ch)
{
	while (ch=getchar(),ch!='0'&&ch!='1');
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; for (scanf("%d",&n),i=1;i<=n;++i)
		if (get_digit(ch),ch=='0') c[i]=1; else c[i]=0;
		for (ans=0,i=1;i<=n;++i) for (j=i;j<=n;j+=i)
		if (!c[j]) break; else if (c[j]==1) c[j]=2,ans+=i;
		printf("%lld\n",ans);
	}
	return 0;
}

D. Slime Escape

首先由于只有两个出口,且起点到出口的路径上的所有点都一定要经过,因此我们可以考虑先强制定下出口为\(a_0\)(对于出口为\(a_{n+1}\)的情形我们只需要翻转整个序列和\(k\)即可)

那么此时起点右边的点对于我们来说就变成了补充生命值的地方,考虑对于右边的每一个走到它有正收益的位置,记录下它的收益和到达它的最小代价

不难发现由于右边的补给点只能按顺序取,因此我们每次往左边走的时候维护一下右边取到哪个了即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=200005;
struct data
{
	long long c,v;
}b[N]; int t,n,k,a[N];
inline bool solve(void)
{
	RI i,j; long long cur=0,mi=0; int cnt=0; for (i=k+1;i<=n;++i)
	{
		cur+=a[i]; mi=min(mi,cur); if (cur>0) b[++cnt]={mi,cur},mi=cur=0;
	}
	for (cur=a[i=k],i=k-1,j=0;i;--i)
	{
		while (j<=cnt&&cur+b[j].c>=0) cur+=b[j].v,++j;
		if ((cur+=a[i])<0) return 0;
	}
	return 1;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d%d",&n,&k),i=1;i<=n;++i) scanf("%d",&a[i]);
		if (solve()) { puts("YES"); continue; }
		reverse(a+1,a+n+1); k=n-k+1;
		if (solve()) puts("YES"); else puts("NO");
	}
	return 0;
}

E. Rectangular Congruence

又是被动构造题精通触发,话说这场的E怎么都那么水啊

首先把\(a_{r_1, c_1} + a_{r_2, c_2} \not\equiv a_{r_1, c_2} + a_{r_2, c_1} \pmod n\)的条件变成\(a_{r_1, c_1} - a_{r_1, c_2} \not\equiv + a_{r_2, c_1} - a_{r_2, c_2}\pmod n\)

不难发现我们把每一行都构造成模\(n\)时的等差数列即可满足题意,第\(i\)行的公差就是\(i\)(下标从\(0\)开始)

更具体的,令\(a_{i,j}=(j-i+n)\times i+b_i\)

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=355;
int n,b[N];
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i,j; for (scanf("%d",&n),i=0;i<n;++i) scanf("%d",&b[i]);
	for (i=0;i<n;++i) for (j=0;j<n;++j)
	printf("%d%c",((j-i+n)*i+b[i])%n," \n"[j==n-1]);
	return 0;
}
posted @ 2022-09-29 23:29  空気力学の詩  阅读(36)  评论(0编辑  收藏  举报