首页 > 其他分享 >CF补题 950-Div.3

CF补题 950-Div.3

时间:2025-01-05 15:34:37浏览次数:7  
标签:int 950 元素 CF cin fa 补题 数组 序列

CF补题 950-Div.3-20250102

Dashboard - Codeforces Round 950 (Div. 3) - Codeforces

A:

题目大意:给出一个字符串,要求重复的字母必须 \(\ge m\) ,求缺失字母总个数

#include <iostream>
#include <map>
using namespace std;

map<char, int> mp;

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		int n, m;
		int ans = 0;
		char a;
		cin >> n >> m;
		for (int i = 1; i <= n; i++) {
			cin >> a;
			mp[a]++;
		}
		for (char i = 'A'; i <= 'G'; i++) {
			if (m - mp[i] >= 0)
				ans += m - mp[i];
		}
		cout << ans << endl;
		mp.clear();
	}
}

map 存储字符串中每个字母的个数,最后计算需要增添的字母总个数

B:

题目大意:给出一个序列,标记其中一个元素,从大到小排序后,前 \(k\) 个元素是否能包含这个标记的元素

#include <iostream>
using namespace std;

int a[105];
int fa;

bool cmp(int a, int b) {
	return a > b;
}

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		memset(a, 0, sizeof a);
		int n, f, k;
		cin >> n >> f >> k;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			if (i == f) fa = a[i];
		}
 		sort(a + 1, a + n + 1, cmp);
		if (a[k] > fa) cout << "NO" << endl;
		else if (a[k] < fa || (a[k] == fa && a[k + 1] < fa)) cout << "YES" << endl;
		else cout << "MAYBE" << endl;
	}
}

sort 从大到小排序,判断前 \(k\) 个元素是否能包含 \(fa\)

  • 第 \(k\) 个元素的值小于 \(fa\) ,绝对包含
  • 第 \(k\) 个元素的值大于 \(fa\) ,绝对不包含
  • 第 \(k\) 个元素的值等于 \(fa\) ,存在两种可能
    • 值为 \(fa\) 的元素只有一个,那么肯定包含 a[k] == fa && a[k + 1] < fa
    • 值为 \(fa\) 的元素不止一个,有可能包含

C:

题目大意:给定两个序列a,b,再给定一个修改序列d,问能否通过修改序列使得第一个序列变为第二个序列

\((c_i,d_i)\) 表示 d 序列中的第 \(c_i\) 项能把 a 中一个元素变为 \(d_i\) ,必须依次执行 d 的变化操作

#include <iostream>
#include <map>
using namespace std;

int a[200010];
map<int, int> b, mp;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

	int T;
	cin >> T;
	while (T--)
	{
		bool flag = 0;
		int n,cnt=0;
		cin >> n;
		for (int i = 1; i <= n; i++) cin >> a[i];
		
		int tb;
		for (int i = 1; i <= n; i++) {
			cin >> tb;
			b[tb]++;
			if (tb != a[i]) {
				mp[tb]++;
				cnt++;
			}
		}
		
		int m, d;
		cin >> m;
		
		for (int i = 1; i <= m; i++) {
			cin >> d;
			if (mp[d]) {
				mp[d]--;
				cnt--;
			}
			if (i == m && !b[d]) flag = 1;
		}
		
		if (cnt|| flag == 1) cout << "NO" << endl;
		else cout << "YES" << endl;
		mp.clear();
		b.clear();
	}
}

map 来存 bmp 数组,mp 数组用来 记录那些元素需要发生改变

最后输入 d ,每次判断当前的元素是否能够被用来改变 a 数组,如果能,那么mp数组内的对应元素 \(-1\)

当输入到 d 的最后一个元素时,判断这个元素是否存在 b 中,如果不在 b 中,那么我们就需要把 a 数组内的某个元素改为不需要的值,这样就不能做到把 a 完全转化成 b

多测要清空

D:
题目大意:给定一个序列a,判断删去其中一个数后能否使a的最大公约数数组 b 实现不减序列

#include <iostream>
using namespace std;

int a[200010];
int b[200010];
bool l[200010];
bool r[200010];

int gcd(int x, int y) {//计算gcd
	return y == 0 ? x : gcd(y, x % y);
}

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		int n;
		cin >> n;
		for (int i = 1; i <= n; i++) cin >> a[i];//读入a
		for (int i = 1; i < n; i++) b[i] = gcd(a[i], a[i + 1]);//预处理gcd数组b
		                              
		l[0] = 1;
		for (int i = 1; i < n; i++) l[i] = l[i - 1] && b[i - 1] <= b[i];

		r[n] = r[n - 1] = 1;
		b[n] = 1e9;
		for (int i = n - 2; i > 0; i--) r[i] = r[i + 1] && b[i + 1] >= b[i];

		bool ans = l[n - 2] || r[2];
		for (int i = 2; i < n; i++) {
			int t = gcd(a[i - 1], a[i + 1]);
			ans |= l[i - 2] && r[i + 1] && (b[i - 2] <= t && b[i + 1] >= t);
		}

		if (ans) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}

预处理b数组后,从数组两侧进行扫描,判断b数组的什么位置开始,是一段完整的不减序列

  • l从左侧开始扫描,当 b[i] 小于 b[i-1] 时说明截至到i,前面的序列都不减
  • r从右侧开始扫描,当 b[i] 大于 b[i+1] 时说明截至到i ,之后的序列都不减

可以删去一个数a[i],这个数会影响到 gcd(a[i-1],a[i])gcd(a[i],a[i+1])

判断删去 a[i] 是否合理时,需要判断 l[i-2]r[i+1] 是否都处于不减区间内(必要条件)

同时还需要判断 b[i - 2] <= t && b[i + 1] >= t 删去的这个数能否和前后构成不减序列

为什么不枚举 a 数列的两个端点呢?

这是因为端点的影响在 bool ans = l[n - 2] || r[2]; 这一步已经做出了判断

  • l[n - 2]:这个条件检查了如果移除数组 a 的最后一个元素 a[n-1],剩余数组的最大公约数序列是否非递减

  • r[2]:这个条件检查了如果移除数组 a 的第一个元素 a[1],剩余数组的最大公约数序列是否非递减

例如 2,4,8,1,这个序列,b数组就为 2,4,1

l = {1, 1, 1, 0, 0}
r = {0, 0, 0, 1, 1}
ans = 1||0 

标签:int,950,元素,CF,cin,fa,补题,数组,序列
From: https://www.cnblogs.com/dianman/p/18653389

相关文章

  • [CF2053E] Resourceful Caterpillar Sequence 题解
    显然两步之内决胜负。否则两个人会来回拉扯,平局。考虑何时Aron会赢。称与叶子结点边距离小于等于\(1\)的结点为【制胜点】。开局\(q\)在叶子,\(p\)不在叶子,直接赢。方案数\(c(n-c)\),其中\(c\)为叶子数量。\(q\)在一个连着【制胜点】的点,\(p\)不在【制胜点】。Nora......
  • [CF2043D] Problem about GCD 题解
    首先的一个观察是可以把\(G\)除掉,转化成\([\lceil\frac{l}{G}\rceil,\lfloor\frac{r}{G}\rfloor]\)中的两个互质数的差最大值。然后的性质非常神奇。令\(l'\gets\lceil\frac{l}{G}\rceil,r'\gets\lfloor\frac{r}{G}\rfloor\)。若\(r'-l'\)充分大,则一定有一组......
  • CF2053F Earnest Matrix Complement
    CF2053FEarnestMatrixComplement题意:多测每次给定\(n,m,k\),存在一个\(n\timesm\)的表格,其中\(a_{i,j}\in{[1,k]\\text{and}\-1}\)令\(c_{i,j}=\sum_{p=1}^m{[a_{i,p}=j]}\)最后\(V=\sum_{i=2}^n\sum_{j=1}^{n\timesm}c_{i-1,j}......
  • AtCoder Beginner Contest 386 补题
    E-MaximizeXOR题目大意给出\(n\)个数,要选\(k\)个使异或和最大。\(n\leq2\times10^5,k\leqn\)\(C_n^k\leq10^6\)思路由于那个组合数的性质,发现应该是直接深搜就可以的。可是发现T了。发现如果\(k\)很大那么还是不好处理。但是发现搜\(k\)个数和搜\(n-k\)个......
  • 题解:CF1830A Copil Copac Draws Trees
    首先这道题肯定不能暴力枚举,我们要思考其他算法。我们可以给每一条边编一个号。然后从根开始遍历这棵树,当一条边的编号比他祖先到他祖先的祖先的那条边的编号还要小时,就说明顺序错了,要再等一轮。这个就简单了,直接dfs就行,注意答案要加\(1\)。#include<bits/stdc++.h>using......
  • 题解:CF2044D Harder Problem
    CF2044DHarderProblem思路构造一个\(1\simn\)都出现了一次的数列(这样每个数都是众数了),然后只要保证在数组\(a\)里面出现了的数在最前面就好了。AC代码#include<bits/stdc++.h>usingnamespacestd;#defineN200005longlongt,vis[N],cnt,n,a[N];intmain(){ cin......
  • 602 [CF 1385D] a-Good String
    //602[CF1385D]a-GoodString.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/22/problem/978给你一个长度为n的由小写字母组成的字符串s,保证n=2k,其中k为大于等于零的整数。一个非空字符串s被称为c-good(c为a.........
  • CF1110D Jongmah
    经典题。\(\tt{Link}\)题意你手中有$$\(n\)$$张牌。每张牌上都写着一个介于\(1\)和\(m\)之间的整数。要赢得游戏,需要组成一定数量的三元组。每个三元组由三张牌组成,这样写在牌上的数字要么全部相同,要么连续。例如,\(7,7,7\)和\(12,13,14\)都是有效的三连牌,但\(2,......
  • [CF2353D] Refined Product Optimality 题解
    首先让我们输出的是不操作的值。不定序,一看就很贪心。经过分类分类分类可证,\(a,b\)都是升序(降序)的时候是最优的。再看加操作的。相当于要维护这两个升序序列。我们发现,每次操作影响的值很少,最多两个值。在一个连续段中,修改的值相当于和末尾值交换,再加一。唐点:找这个末尾没必要......
  • CF848E Days of Floral Colours 题解
    Problem-848E-Codeforces首先,由于整个图是对称的,所以我们将其沿直径分为两半,在算一半答案时把每一段的贡献平方再相加即可。(因为对面也有一段相同长度的也要计入贡献)现在我们的问题转化为了对于一个长为\(n\)的环,你可以给一个点连出一个线头(即在原图中连向对面的边)将其余......