Codeforces Round 1017 (Div. 4)

老实说,有了翻译,确实更好写了

A

输入三个字符串,取首位连接输出

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int t;
void solve(){
	string s[4];
	for(int i=1;i<=3;++i) cin>>s[i];
	for(int i=1;i<=3;++i) cout<<s[i][0];
	cout<<endl;
}

int main(){
	cin>>t;
	while(t--){
		solve();
	} 
	return 0;
	
} 

B

破翻译有点问题,看了半天题,注意它是从中间开始传染的

所以只需要构造一个长度为m的区间,其包含0,同时处于[l,r]之间

我的构造是,尽量往左延申,左边不足了就往右

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int t;
int n,m,l,r; 
void solve(){
	cin>>n>>m>>l>>r;
	if(-l>m){
		cout<<-m<<" "<<0<<endl; 
	} 
	else {
		cout<<l<<" "<<l+m<<"\n";
	}
	return ; 
}

int main(){
	cin>>t;
	while(t--){
		solve();
	} 
	return 0;
	
} 

C

这就更简单了,i+j这个位置已经被确定了,只剩下唯一一个位置(也就是第一个位置)没有数,所以只需要第一个位置输出没有出现过的数就行

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int t;
const int maxn=810;
int n;
int a[maxn<<1]; 
int mp[maxn<<1];
void solve(){
	cin>>n;
	memset(mp,0,sizeof(mp));
	memset(a,0,sizeof(a));
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			int x;cin>>x;
			a[i+j]=x;
			mp[x]=1;
		}
	for(int i=1;i<=2*n;++i)
		if(a[i]==0){
			for(int j=1;j<=2*n;++j)
				if(mp[j]==0) a[i]=j;
			break; 
		}
	for(int i=1;i<=2*n;++i)
		cout<<a[i]<<" ";
	cout<<endl;
}

int main(){
	cin>>t;
	while(t--){
		solve();
	} 
	return 0;
	
} 

D

其实也就是说L可以扩展LL,R同理

所以考虑不可能的情况

  1. 由于字符串是LR相交的,所以两个字符串,L,R的交替次序必须一一对应.

  2. 如果连续的L全部扩展完之后都没有比对应连续L的更长,那么就不可能

  3. 但是如果这一段L或R本身就比需要扩展后L或R长,那么更不可能,因为无法缩减

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int t;
int n;

void solve(){
	string s,p;
	cin>>s>>p;
	int lens=s.length(),lenp=p.length();
	if(lenp>lens*2){
		puts("NO");
		return ;
	} 
	s=" "+s;p=" "+p; 
	int i=1,j=1;
	for(;i<=lens && j<=lenp;++i,++j){
		int l=i;
			while(s[i]==s[i+1] && i<lens){
				++i;
			}
			int xa=i-l+1;
			if(p[j]!=s[i]){
				puts("NO");
				return ;
			}
			int r=j;
			while(p[j]==p[j+1] && j<lenp){
				++j;
			}
			int xb=j-r+1;
			if(xa*2<xb || xb<xa){
				puts("NO");
				return ;
			}
		
	} 
	if(i!=lens+1 || j!=lenp+1){
		puts("NO");
		return ;
	}
	puts("YES");
	return ;

}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0); 
	cin>>t;
	while(t--){
		solve();
	} 
	return 0;
	
} 

E

如果暴力无法计算,换个角度计算,应该是经典套路(一开始想麻烦了,推性质)

直接每个数互相异或一定会超时,但是不妨换个角度,按照二进制位,一位一位的算.

具体的,我们统计每个二进制位上的0,1数量,然后枚举所有的a,然后计算每一位与a异或后的结果再相加

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring> 

using namespace std;
#define ll long long  
int t;
int n;
const int maxn=2e5+10;
ll a[maxn];
int cnt[33][5];
ll quick_pow(ll a,ll b){
	ll cnt=1;
	ll base=a;
	while(b){
		if(b&1){
			cnt*=base;
		}
		base*=base;
		b>>=1;
	}
	return cnt;
}
void solve(){
	cin>>n;
	memset(cnt,0,sizeof(cnt));
	for(int i=1;i<=n;++i) cin>>a[i];
	for(int j=0;j<=29;++j){
		for(int i=1;i<=n;++i){
			if((a[i]>>j)&1) cnt[j][1]++;
			else cnt[j][0]++;
		}
	}
	ll ans=0;
	for(int i=1;i<=n;++i){
		ll num=0;
		for(int j=0;j<=29;++j){
			if((a[i]>>j)&1){
				num+=cnt[j][0]*quick_pow(2,j);
			}
			else num+=cnt[j][1]*quick_pow(2,j);
		}
		ans=max(num,ans);
	}
	cout<<ans<<"\n";
	return ;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0); 
	cin>>t;
	while(t--){
		solve();
	} 
	return 0;
	
} 
posted @ 2025-04-15 15:39  归游  阅读(19)  评论(0)    收藏  举报