Codeforces Round 896 (Div. 2) A-D2

A. Make It Zero

没看懂这个 8 次的限制是什么意思。先用一次直接把所有数变成 i=1nai,如果 n 是偶数直接 [1,n] 做完,如果是奇数先把 [1,n1] 变成 0,再做两遍 [n1,n] 即可。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int a[100005];
void solve(){
	int n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	if(n%2==0){
		printf("2\n1 %lld\n1 %lld\n",n,n);
	} 
	else{
		printf("4\n1 %lld\n1 %lld\n%lld %lld\n%lld %lld\n",n,n-1,n-1,n,n-1,n);
	}
}
signed main(){
	int T=read();
	while(T--)solve(); 
	return 0;
}

B. 2D Traveling

ab 的最短路只有两种可能:a 直接到 ba,b 到主要城市的最短路之和。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int n,k,a,b,x[200005],y[200005];
int dist(int i,int j){
	if(i<=k&&j<=k)return 0;
	return abs(x[i]-x[j])+abs(y[i]-y[j]);
}
void solve(){
	n=read(),k=read(),a=read(),b=read();
	for(int i=1;i<=n;i++)x[i]=read(),y[i]=read();
	int ans=dist(a,b),da=inf,db=inf;
	for(int i=1;i<=k;i++)da=min(da,dist(a,i));
	for(int i=1;i<=k;i++)db=min(db,dist(b,i));
	ans=min(ans,da+db);
	printf("%lld\n",ans);
}
signed main(){
	int T=read();
	while(T--)solve(); 
	return 0;
}

C. Fill in the Matrix

nm1 时,答案就是 m;反之,答案是 n+1。最大值显然,给一个构造:当 n=m1 时,令 ai,j=(i+j)modm,i[0,n),j[0,m) 即可。如果 n>m1 就复制最后一行,如果 n<m1 就把 m 当成 n+1,每一行后面随便填。

特判一下 m=1n=1

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void solve(){
	int n=read(),m=read();
	if(n==1&&m==1){
		printf("0\n");
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				printf("0 ");
			}
			puts("");
		}
		return;
	}
	if(m==1){
		printf("0\n");
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				printf("0 ");
			}
			puts("");
		}
		return;
	}
	if(n==1){
		printf("2\n");
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				printf("%lld ",j);
			}
			puts("");
		}
		return;
	}
	if(n>=m-1){
		printf("%lld\n",m);
		for(int i=0;i<m-1;i++){
			for(int j=0;j<m;j++){
				printf("%lld ",(i+j)%m);
			}
			puts("");
		}
		for(int i=m-1;i<n;i++){
			for(int j=0;j<m;j++){
				printf("%lld ",(m-2+j)%m);
			}
			puts("");			
		}
		return;
	}
	else{
		int M=n+1;printf("%lld\n",M);
		for(int i=0;i<n;i++){
			for(int j=0;j<M;j++){
				printf("%lld ",(i+j)%M);
			}
			for(int j=M;j<m;j++){
				printf("%lld ",j);
			}
			puts("");
		}
		return;		
	}
}
signed main(){
	int T=read();
	while(T--)solve(); 
	return 0;
}

D1. Candy Party (Easy Version)

首先平均数不是整数不行,每个数与平均数的差不能写成 2x2y 的形式不行。然后我们开个桶看一下每一位是不是一样多。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int a[200005],cnt[1005];
void solve(){
	for(int i=0;i<=100;i++)cnt[i]=0;
	int n=read(),s=0;
	for(int i=1;i<=n;i++)a[i]=read(),s+=a[i];
	if(s%n)return puts("No"),void();
	s/=n;
	for(int i=1;i<=n;i++){
		if(s>=a[i]){
			int o=s-a[i],p1=0,p2=0;
			while(o&&o%2==0)o/=2,p1++;
			p2=p1;while(o&&o%2==1)o/=2,p2++;
			if(o)return puts("No"),void();
			cnt[p1]++,cnt[p2]--;
		}
		else{
			int o=a[i]-s,p1=0,p2=0;
			while(o&&o%2==0)o/=2,p1++;
			p2=p1;while(o&&o%2==1)o/=2,p2++;
			if(o)return puts("No"),void();	
			cnt[p1]--,cnt[p2]++;
		}
	}
	for(int i=0;i<=100;i++)if(cnt[i]!=0)return puts("No"),void();
	puts("Yes");
}
signed main(){
	int T=read();
	while(T--)solve(); 
	return 0;
}

D2. Candy Party (Hard Version)

考试的时候蠢了。这个题在上一个题的基础上多了一种选择:当差可以表示成 2x 时,我们既可以当成 2x 也可以当成 2x+12x。那我们先统计那些只有一种选择的数的影响,再考虑这些有两种选择的数该怎么选。因为一个 |aiaverage|=2i 选择表示为 2i+12i,那么它会影响 i,i+1 位,否则只会影响 i 位。所以我们从高到低决定就行了。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int a[200005],cnt[1005],v[2][1005];
void solve(){
	for(int i=0;i<=100;i++)cnt[i]=v[0][i]=v[1][i]=0;
	int n=read(),s=0;
	for(int i=1;i<=n;i++)a[i]=read(),s+=a[i];
	if(s%n)return puts("No"),void();
	s/=n;
	for(int i=1;i<=n;i++){
		if(s>a[i]){
			int o=s-a[i],p1=0,p2=0;
			while(o&&o%2==0)o/=2,p1++;
			p2=p1;while(o&&o%2==1)o/=2,p2++;
			if(o)return puts("No"),void();
			if(p2!=p1+1)cnt[p1]++,cnt[p2]--;
			else v[1][p1]++;
		}
		else if(s<a[i]){
			int o=a[i]-s,p1=0,p2=0;
			while(o&&o%2==0)o/=2,p1++;
			p2=p1;while(o&&o%2==1)o/=2,p2++;
			if(o)return puts("No"),void();	
			if(p2!=p1+1)cnt[p1]--,cnt[p2]++;
			else v[0][p1]++;
		}
	}
	for(int i=100;i>=1;i--){
		int val=cnt[i]+(v[0][i]-v[1][i]);
		if(val>0){
			if(v[1][i-1]<val)return puts("No"),void();
			v[1][i-1]-=val,cnt[i-1]+=val;
		}
		else if(val<0){
			if(v[0][i-1]<-val)return puts("No"),void();
			v[0][i-1]-=-val,cnt[i-1]-=-val;
		}
	}
	if(cnt[0]+(v[0][0]-v[1][0])==0)puts("Yes");
	else puts("No");
}
signed main(){
	int T=read();
	while(T--)solve(); 
	return 0;
}
posted @   xx019  阅读(141)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示