Codeforces Round 966 (Div. 3)

A - Primary Task

给一个数 x10000,判断其是否形如 ab 满足 a=10,b2 且无前导零。

模拟判断即可。

code
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+3;
int T;
string n;
void solve(){
	cin>>n;
	if((n=="1"||n=="101"||n=="10"||n=="100"||n=="1000"||n=="10000")||n.size()==1||n[0]!='1'||n[1]!='0'||n[2]=='0'){
		cout<<"No\n";
	}else{
		cout<<"Yes\n";
	}
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

B - Seating in a Bus

车上有 n 个座位,有 n 个人要上车,判断这 n 个人上车顺序是否合法:

  • i=1 合法;
  • 若座位 ai1ai+1 不为空则合法,否则不合法;
  • 若合法则 i 在座位 ai 坐下。

同样边模拟边判断即可。

code
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+3;
int T;
int n;
int a[maxn];
int b[maxn];
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
		if(i==1) b[a[i]]=1;
		else{
			if(b[a[i]-1]||b[a[i]+1]) b[a[i]]=1;
			else{
				cout<<"NO\n";
				return;
			}
		}
	}
	cout<<"YES\n";
}
signed main(){
	cin>>T;
	while(T--){
		solve();
		for(int i=1;i<=n;i++) b[a[i]]=0;
	}
	return 0;
}

C - Numeric String Template

给一个数字串 a 以及一个字符串 s,判断 s 是否为模板串

模板串定义:

  • |s|=n
  • 对于每一个相同的 si 有唯一的 ai(值)与其匹配
  • 对于每一个相同的 ai 有唯一的 si(值)与其匹配

n2×105,|ai|2×109

唐氏。没看见 ai 可以为 0(你CF的 pretest 也太水了罢我去),被 hack 了。

在遍历 s 的时候,分类讨论:

  • si 未出现过:若 ai 对应了另一个字符,则 s 不是模板串;
  • si 出现过:若 ai 对应了另一个字符,或者 si 对应了另一个值,则 s 不是模板串。

开两个 map 判断即可,注意要么使用 .count(a[i]/s[i])要么初值要赋值为绝对值大于 2×109 的数!!

code
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+3;
int T;
int n;
int a[maxn];
int b[26];
map<int,bool>mp;
void ss(){
	string s;
	cin>>s;
	if(s.size()!=n){
		cout<<"NO\n";
		return;
	}
	for(int i=1;i<=n;i++){
		if(b[s[i-1]-'a']==INT_MAX){
			if(mp[a[i]]){
				cout<<"NO\n";
				return;
			}
			mp[a[i]]=1;
			b[s[i-1]-'a']=a[i];
			
		} 
		else{
			if(b[s[i-1]-'a']!=a[i]){
				cout<<"NO\n";
				return;
			}
		}
	}
	cout<<"YES\n";
	
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int t;
	cin>>t;
	while(t--){
		ss();
		for(int i=0;i<26;i++) b[i]=INT_MAX;
		mp.clear();
	}
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

D - Right Left Wrong

给你一个长为 n 的数列 a(ai>0) 和 LR 串 s

进行任意次操作:

  • 选择两个位置 l,r 满足 sl=L,sr=R,将答案加上 a[l,r] 的和,并将 s[l,r] 置为 .

求得到的最大答案。

考虑贪心地取最左边的 L 和最右边的 R,这样得到的和一定是最大的(实际操作顺序是从里到外)。

code
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e5+3;
int T;
int n;
int a[maxn],pre[maxn];
char s[maxn];
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		pre[i]=pre[i-1]+a[i];
	}
	cin>>s;
	int l=0,r=strlen(s)-1,ans=0;
	while(l<r){
		while(l<r&&s[l]!='L') l++;
		while(l<r&&s[r]!='R') r--;
		if(l<r){
			ans+=pre[r+1]-pre[l];
			l++,r--;
		}
	}
	cout<<ans<<'\n';
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

E - Photoshoot for Gorillas

给你一个 n×m 的网格,另有 w 个猩猩,权值为 ai,将所有将猩猩放入不同的网格中,总得分为每个 k×k 的子网格的权值之和,求最大得分。

wn×m2×105,kmin(n,m)

首先考虑将 a 排序,然后将最大值放到被最多子网格覆盖的地方,依此类推。

对于每个格子 (i,j),其被覆盖次数的计算公式为 min(i,ni+1,k,nk+1)min(j,mj+1,k,mk+1),这个画图理解即可。

时间复杂度 O(mn+w)

code
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e5+3;
int T;
int n,m,ans,k,w;
int a[maxn];
int stk[maxn],top;
void solve(){
	ans=0;
	top=0;
	cin>>n>>m>>k;
	cin>>w;
	for(int i=1;i<=w;i++){
		cin>>a[i];
	}
	sort(a+1,a+w+1,greater<int>());
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			int t=(min(min(i,n-i+1),min(k,n-k+1)))*(min(min(j,m-j+1),min(k,m-k+1)));
			stk[++top]=t;
		}
	}
	sort(stk+1,stk+top+1,greater<int>());
	for(int i=1;i<=w;i++){
		ans+=stk[i]*a[i];
	}
	cout<<ans<<'\n';
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

F - Color Rows and Columns

给你 nai×bi 的矩阵,每次你可以选择一个矩阵并填充一个格子,当你每填满一行或一列格子时,得分加一,求到达 k 分的最少操作次数。

n1000,ai,bi,k100

容易发现每个操作的顺序不重要,每个矩阵的得分是独立的,设 gi,k 为在第 i 个矩阵中,得到 k 分的最小操作次数。

这可以贪心去求,每次填充较短的一变即可。注意当剩余一个格子时,填充会得到两分,即无法得到 2(ai+bi)1 分。

剩下的就是背包问题了,设 fi,k 表示目前在背包 i,获得了 k 分的最小操作次数,则有转移:

fi,k=minj=0k(fi1,kj+gi,j)

再次注意,由于我们得不到 2(ai+bi)1 分,所以可能最后实际得分大于 k,所以答案需要在 fn,[k,k+n] 之间取个 min

时间复杂度 O(n(k+(ai+bi)))

code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+3;
const int maxk=1100+3;
int T;
int n,k;

set<int>s;
priority_queue<int>q[maxk<<1];
int a[maxn],b[maxn];
int g[maxn][maxk],cnt[maxn];
int f[maxn][maxk];// 到 i,旋了 j 个
void ss(int i,int x,int y){
	cnt[i]=0;g[i][0]=0;
	while(x){
		if(x>y) swap(x,y);
		if(!x) break;
		++cnt[i];
		g[i][cnt[i]]=g[i][cnt[i]-1]+x;
		y--;
	}
	cnt[i]++;
	g[i][cnt[i]]=g[i][cnt[i]-1];
	g[i][cnt[i]-1]=0x3f3f3f3f;
}
void solve(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=k+n;j++)
			f[i][j]=g[i][j]=0x3f3f3f3f;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i],ss(i,a[i],b[i]);
	for(int i=1;i<=k+n;i++) f[1][i]=g[1][i];
	for(int i=2;i<=n;i++){
		for(int j=1;j<=k+n;j++){
			for(int l=0;l<=j;l++){
				f[i][j]=min(f[i][j],f[i-1][j-l]+g[i][l]);
			}
		}
	}
    int ans=0x3f3f3f3f;
    for(int i=k;i<=n+k;i++) ans=min(ans,f[n][i]);
    if(ans==0x3f3f3f3f) cout<<"-1\n";
    else cout<<ans<<'\n';
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

G - Call During the Journey

H - Ksyusha and the Loaded Set

posted @   view3937  阅读(139)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
Title
点击右上角即可分享
微信分享提示