首页 > 其他分享 >Codeforces Round 966 (Div. 3) (A~F)

Codeforces Round 966 (Div. 3) (A~F)

时间:2024-08-18 10:53:55浏览次数:8  
标签:966 code cout int cin Codeforces -- Div 思路

文章目录

Codeforces Round 966 (Div. 3)

写在前面

赛时写的还挺快的,50分钟就A了4道题,当时排名已经到2千多了,后面就坐牢1个多小时······,E题一开始想用贪心先把猴子放在网格图的中间,后面觉得实现起来太麻烦了,直接做F题了,赛时也是用的贪心,没过,赛后想了想应该用DP的,本质上就是背包问题,当时没想到这点,DP学了还是不会用,题型还是见太少了····

A- Primary Task

思路

签到题,字符串长度为1或者2 or 字符串前两个字符不为1 0,都输出no
接着特判第三个字符是否为0,还有当长度为3时,第三个字符必须大于1
其他情况输出YES

code

void solve(){
	string s;cin >> s;
	if(s.size()==1 || s.size()==2){
		cout << "NO" << endl;
		return ;
	}
	if(s[0]!='1' || s[1]!='0'){
		cout << "NO" << endl;
		return ;
	} 
	if(s.size()==3 && s[2]<='1' || s[2]=='0'){
		cout << "NO" << endl;
		return ;
	}
	cout << "YES" << endl;
	return ;
}

B. Seating in a Bus

思路

除了第一个人,其他人都需要判断当前座位的左右两边是否有人,用一个标记数组即可

code

int a[N],v[N];
void solve(){
	int n;cin >> n;
	for(int i=1;i<=n;++i) cin >> a[i];
	for(int i=1;i<=n+1;++i) v[i]=0;
	v[a[1]]=1;
	for(int i=2;i<=n;++i){
		int flag=0;
		if(v[a[i]-1]){
			flag=1;
			v[a[i]]=1;
		} 
		if(v[a[i]+1]){
			v[a[i]]=1;
			flag=1;
		} 
		if(flag==0){
			cout << "NO" << endl;
			return ;
		}
	}
	cout << "YES" << endl;
	return ;
}

C- Numeric String Template

思路

考点:模拟

除了第一个字符,其他字符都需要判断当前字符和数字是否一一对应
这时我们需要开两个map数组,一个map是字符判断数字,另一个map是数字判断字符
注意:数字可能为0,所以当数字为0时将0赋值成另一个值即可

code

int a[N];
void solve(){
	int n;cin >> n;
	for(int i=1;i<=n;++i) cin >> a[i];
	int m;cin >> m;
	while(m--){
		int flag=1;
		string s;cin >> s;
		if(s.size()!=n){
			cout << "NO" << endl;
			continue;
		}
		s=' '+s;
		unordered_map<char,int> m2;
		unordered_map<int,char> m1;
		if(a[1]==0) a[1]=1e10;
		m1[a[1]]=s[1];
		m2[s[1]]=a[1];
		for(int i=2;i<=n;++i){
			if(a[i]==0) a[i]=1e10;
			if(m1[a[i]]==0 && m2[s[i]]==0){
				m1[a[i]]=s[i];
				m2[s[i]]=a[i];
			}
			else{
				if(m1[a[i]] && m1[a[i]]!=s[i]){
					cout << "NO" << endl;
					flag=0;
					break;
				}
				if(m2[s[i]] && m2[s[i]]!=a[i]){
					cout << "NO" << endl;
					flag=0;
					break;
				}
				m1[a[i]]=s[i];
				m2[s[i]]=a[i];
			}
		}
		if(flag) cout << "YES" << endl;
	}
	return ;
}

D- Right Left Wrong

思路

考点:贪心+双指针

由于内层的LR不会影响外层的LR,但是外层的LR会影响内层的LR
好比LLRR,先选里面的LR,不会影响外面的LR

这时,我们就需要从外层开始遍历,l指针为0,r指针为n
每次左指针找到L,右指针找到R,就将里面的值全部加起来
在遍历之前需要先对数组进行前缀和,方便后续相加

code

int a[N],sum[N];
void solve(){
	int n;cin >> n;
	for(int i=1;i<=n;++i){
	   cin >> a[i];
	   sum[i]=sum[i-1]+a[i];	
	} 
	string s;cin >> s;
	s=' '+s;
	int ans=0;
	int pos1=1,pos2=n;
	while(1){
		int k1=s.find('L',pos1);
		int k2=s.rfind('R',pos2);
		if(k1==-1 || k2==-1) break;
		for(int i=pos1;i<=k1;++i) s[i]='.';
		for(int i=k2;i<=pos2;++i) s[i]='.';
		ans+=sum[k2]-sum[k1-1];
		pos1=k1+1;
		pos2=k2-1;
	}
	cout << ans << endl;
	return ;
}

E- Photoshoot for Gorillas

思路

考点:数学思维

首先我们想让价值尽可能大,很容易想到先让数字大的放在网格中间,那么我们只需要考虑每个网格能被扫描几次即可

我们先拿列数来说,如果当前列数小于矩阵k,那么它能被扫描的次数自然也就是它的下标j,否则它能被扫描的次数就为k
这时我们就需要考虑它是否超出右边界,如果超出右边界,就需要减去超出的数量
因此,它的公式就为 m i n ( k , j + 1 ) − m a x ( j + k − m , 0 l l ) min(k,j+1)-max(j+k-m,0ll) min(k,j+1)−max(j+k−m,0ll)

行数同理,接着我们将数组从大到小排序,将他们放入进去即可

code

bool cmp(int x,int y){
	return x>y;
}
void solve(){
	int n,m,k;
	cin >> n >> m >> k;
	int w;cin >> w;
	vector<int> a(w),cnt;
	for(auto &x : a) cin >> x;
	for(int i=0;i<n;++i)
	   for(int j=0;j<m;++j){
	   	int x=min(k,j+1)-max(j+k-m,0ll);
	   	int y=min(k,i+1)-max(i+k-n,0ll);
	   	cnt.push_back(x*y);
	   }
	sort(a.begin(),a.end(),cmp);
	sort(cnt.begin(),cnt.end(),cmp);
	int ans=0;
	for(int i=0;i<w;++i){
		ans+=a[i]*cnt[i];
	}
	cout << ans << endl;
	return ;
}

F- Color Rows and Columns

思路

考点:贪心+背包DP
首先我们可以将分数看成重量,将操作数看成价值
既然是DP,我们可以开两个一维数组,一个存总体数据,一个存动态数据(由于是一维,当前状态不能影响上一层的状态,需要多开一个数组
对于每次的长度和宽度,我们可以用贪心去考虑,每次都填入长度小的那一个
这时我们需要特判一下,当 a = 1 并且 b = 1 a=1 并且 b=1 a=1并且b=1,那么填入这个格子,它的分数是+2的
每操作一次,我们就对当前价值和重量进行01背包的处理
由于上述可能会出现+2的情况,我们最终的分数k+1可能会比分数k的操作数更少,所以在进行DP时,它的上限为k+1
最后比较 f [ k ] 和 f [ k + 1 ] f[k]和f[k+1] f[k]和f[k+1] 的大小即可

code

const int inf=1e9;
void solve(){
	int n,k;
	cin >> n >> k;
	vector<int> f(k+3,inf),g(k+3,inf);
	f[0]=0;
	for(int i=1;i<=n;++i){
		int a,b;
		cin >> a >> b; 
		int w=0,v=0;
		g=f;
		while(w<=k && a && b){
			w++;
			if(a>b){
				v+=b;
				a--;
			}
			else if(a<b){
				v+=a;
				b--;
			}
			else{
				if(a==1){
					v+=1;
					w++;
					a--,b--;
				}
				else{
					v+=b;
					a--;
				}
			}
			for(int j=k+1;j>=w;--j){
			   g[j]=min(g[j],f[j-w]+v);
		    }
		}
		f=g;
	}
	int ans=min(f[k],f[k+1]);
	cout << (ans==inf? -1 : ans) << endl;
	return ;
}

标签:966,code,cout,int,cin,Codeforces,--,Div,思路
From: https://blog.csdn.net/wh233z/article/details/141207833

相关文章

  • cf966:E. Photoshoot for Gorillas(一个格子被多少个方格包裹了)
    题目你非常喜欢大猩猩,于是决定为它们组织一次拍摄活动。大猩猩生活在丛林中,丛林被表示为一个有......
  • CF Round 966 Div3
    A给定一个字符串,判断是不是大于等于10210^2102的形式,例如......
  • Codeforces 169 Div2
    AClosestPoint由题意可得三个及以上的点无法插入新的点,只有两个点时可以插入但当两个点间隔为1时同样无法插入先判断,后输出就行#include<bits/stdc++.h>usingnamespacestd;constintN=50;intt,n;inta[N];intmain(){ cin>>t; while(t--){ cin>>n; for(i......
  • 自创CodeForcesHelperv1.0,解决CF太卡和跳题问题,代码持续更新!
    文章目录前言一、方法二、源代码三、使用方法四、效果展示总结前言对于OIers来说,Codeforces是一个很好的外国OJ。洛谷上确实收录了大部分CF的题,但是最近由于Codeforces的cloudflare加强了,所以洛谷的爬虫已经无法正确爬取提交记录的数据了,详见link。我......
  • [AGC064C] Erase and Divide Game
    link感觉题解说的都很不清晰,这里只谈个人理解。考虑操作的本质是什么,两人从低到高确定二进制下的每一位填的数,并且场上只保留对应后缀的数字,当场上没有数字时当前操作者输。设\(f[i,S]\)表示确定了前\(i\)位,填的数为\(S\),接下来先手是否能赢,那么有\(f[i,S]=\neg(f[i......
  • Codeforces Round 894 (Div. 3) D
    题目:E.KolyaandMovieTheatre题目链接:https://codeforces.com/contest/1862/problem/E思路:主要用优先队列存放大于0的元素,然后除了第一个数据后的每m个数据就可以存放到记录数组里面,最后遍历找价值最大的点击查看代码#include<bits/stdc++.h>#defineintlonglongusing......
  • codeforces ECR169
    codeforcesECR169A#include<bits/stdc++.h>usingnamespacestd;constintmaxn=50;inta[maxn];voidsolve(){intn;cin>>n;for(inti=1;i<=n;i++)cin>>a[i];if(n==2){if((a[2]-a[1])!=1){......
  • CodeForces 1575F Finding Expected Value
    洛谷传送门CF传送门考虑单个序列如何求答案。考虑鞅与停时定理。定义一个局面的势能为\(\sum\limits_{i=0}^{K-1}f(b_i)\),其中\(f(x)\)是一个关于\(x\)的函数,\(b_i\)为\(i\)的出现次数。那么我们要构造\(f(x)\),使得每次操作,局面势能期望减少\(1\),那么期望步数......
  • Codeforces 232 B Table 题解 [ 蓝 ] [ 分组背包 ] [ 组合数学 ] [ 循环节 ]
    Codeforces232BTable。蒟蒻模拟赛上场切的一道蓝,非常难以置信我竟然能做蓝题。这题的数据范围初看还是比较坑的,\(10^{18}\)的值域很容易让人往矩阵加速那方面想。实际上在列出转移方程式后,我们发现状态是二维的,无法使用矩阵加速(或者说这样做很麻烦)。思路首先观察到每个边长......
  • D. Another Problem About Dividing Numbers
    原题链接题意有两个数\(a,b\)每次可以拿走其中一个数的若干个质因子,请问恰好\(k\)次操作后能否使\(a=b\)分析假设\(a,b\)最后到达的是\(c\),那么\(\frac{a}{c}\)的质因子个数加上\(\frac{b}{c}\)的质因子个数一定大于等于\(k\)(为什么可以大于?因为一次操作可以多......