首页 > 其他分享 >2.3 Codeforces Round #849 (Div. 4)

2.3 Codeforces Round #849 (Div. 4)

时间:2023-02-04 22:13:46浏览次数:48  
标签:cout int void Codeforces cin ++ solve 2.3 Div

记录一下第一次可以写到G1,只剩一道题就可以ak,虽然是div4,不过也值得开心一下。

A - Codeforces Checking

void solve() {
	char c;
	cin >> c;
	string s = "codeforces";
	bool flag = 0;
	for (auto i :s) if (i == c) {
		flag = 1;
	}
	if (flag) cout << "YES" <<endl;
	else cout << "NO" <<endl;
}

\[\]

B - Following Directions

void solve() {
	int n;
	cin >> n;
	string s;
	cin >> s;
	int x = 0, y = 0;
	bool flag = 0;
	for (auto i : s) {
		if (i == 'U') {
			y ++;
		}else if (i == 'D') {
			y --;
		}else if (i == 'R') {
			x ++;
		}else if (i == 'L') {
			x --;
		}
		
		if (x == 1 && y == 1) flag = 1;
	}
	if (flag) cout << "YES" << endl;
	else cout << "NO" << endl;
}

\[\]

C - Prepend and Append

void solve() {
	int n;
	cin >> n;
	string s;
	cin >> s;
	int l = 0, r = n - 1;
	while (l < r) {
		if (s[l] != s[r]) {
			n -= 2;
			l ++, r --;
		}else break;
	}
	
	cout << n << endl;
}

\[\]

D - Distinct Split

题意

给出长度为n的字符串,函数f代表字符串中字符种类数,如f(aba) = 2.问怎么切分可以使给出的字符串两段f之和最大

思路

枚举
用map先将原字符串的字符种类数统计出来作为第二段的种类数,然后从前向后枚举,令0 ~ i为第一段,i + 1 ~ n - 1为第二段。用map统计第一段和第二段的字符种类,然后取最大值即可

void solve() {
	int n;
	cin >> n;
	string s;
	cin >> s;
	map<int, int> mp, p;
	for (int i = 0; i < n; i ++) {
		mp[s[i] - 'a'] ++;
	}
	
	int x = 0, y = mp.size(), ans = 0;
	
	for (int i = 0; i < n; i ++) {
		mp[s[i] - 'a'] --;
		p[s[i] - 'a'] ++;
		if (mp[s[i] - 'a'] == 0) y --;
		if (p[s[i] - 'a'] == 1) x ++;
		
		ans = max(ans, x + y);
	}
	
	cout << ans << endl;
}

\[\]

E - Negatives and Positives

题意

给出长度为n的序列,你可以进行任意次操作,将相邻两个数字的符号变换,即正变负,负变正。问经过操作后序列总和最大值为多少

思路

观察一下变换操作即可得出一下规律,即使不相邻的两个数字也可同时变换符号
如-1 2 2 22 -1
进行若干操作
1 -2 2 22 -1
1 2 -2 22 -1
1 2 2 -22 -1
1 2 2 22 1
这样就简单了。将序列排序,若有负数,负数数量为偶数就可全部变成正数,若数量为奇数,则需要判断是否变换后面那个正数(若还有的话)
若后面那个数的绝对值小于当前负数的绝对值,那么一定是可以取的,否则这个负数就不变换了

void solve() {
	int n;
	cin >> n;
	vector<int> a(n + 1);
	for (int i = 1; i <= n ;i ++) cin >> a[i];
	
	sort(a.begin() + 1, a.end());
	int cnt = 0;
	for (int i = 1; i <= n; i ++) {
		if (a[i] < 0) cnt ++;
	}
	
	if (cnt % 2 == 1) {
		if (cnt + 1 <= n && abs(a[cnt + 1]) <= abs(a[cnt])) {
			cnt ++;
		}else cnt --;
	}
	
	LL sum = 0;
	
	for (int i = 1; i <= n; i ++) {
		if (i <= cnt) {
			a[i] = -a[i];
		}
		sum += a[i];
	}
	
	cout << sum << endl;
}

\[\]

F - Range Update Point Query

题意

给出长度为n的序列,和q次询问。询问1为将区间[l, r]间的每个数变成他们各自每一位上的数之和,如:123变换之后为1 + 2 + 3 = 6
询问2为查询下标为x的数为多少

思路

这题用树状数组+差分水过去的,看到还有用set模拟的大佬

int tr[N], n;
 
inline int lowbit(int x)
{
	return x & -x;
}
 
void add(int x, int c)
{
	for (int i = x; i <= n; i += lowbit(i))
	{
		tr[i] += c;
	}
}
 
int sum(int x)
{
	int res = 0;
	for (int i = x; i; i -= lowbit(i))
	{
		res += tr[i];
	}
	
	return res;
}

void solve() {
	int q;
	cin >> n >> q;
	memset(tr, 0, sizeof (tr));
	vector<int> a(n + 1);
	vector<int> p[n + 1];                                         //存储每个数会变换为什么数
	for (int i = 1; i <= n; i ++) cin >> a[i];
	
	for (int i = 1; i <= n; i ++) {
		int k = a[i];
		if (k < 10) p[i].push_back(k);
		while (k >= 10) {
			int num = 0;
			while (k) {
				int tt = k % 10;
				num += tt;
				k /= 10;
			}
			k = num;
			num = 0;
			p[i].push_back(k);
		}
	}
	
	while (q --) {
		int x;
		cin >> x;
		if (x == 1) {
			int l, r;
			cin >> l >> r;
			add(l, 1), add(r + 1, -1);
		}else {
			int c;
			cin >> c;
			int sz = p[c].size();
			int cnt = sum(c);
			if (cnt == 0) {
				cout << a[c] << endl;
				continue;
			}
			
			if (cnt >= sz) {
				cout << p[c][sz - 1] << endl;
			}else cout << p[c][cnt - 1] << endl;
		}
	}
}

\[\]

G1 - Teleporters (Easy Version)

题意

数字线上的点0,1,…,n。在点1、2、…、n中的每个点上都有一个隐形传态器。在点i,可以执行以下操作:

向左移动一个单位:花费1硬币
向右移动一个单位:成本1硬币

在i点使用传送机,如果存在的话:它需要ai币。结果,你传送到0点。一旦你使用了传送器,你就不能再使用它了。

你有c硬币,从0点开始。你能使用的传送机最多有多少?

思路(贪心)

只从一端开始的话,就是对每个ai都加上i为路程耗费,然后将a数组排序,选出符合条件的传送机即可

void solve() {
	LL n, c;
	cin >> n >> c;
	vector<LL> a(n + 1);
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
		a[i] += i;
	}
	
	sort(a.begin() + 1, a.end());
	
	for (int i = 1; i <= n; i ++) {
		if (c >= a[i]) c -= a[i];
		else {
			cout << i - 1 << endl;
			return ;
		}
	}
	
	cout << n << endl;
}

\[\]

G2 - Teleporters (Hard Version)

题意

跟上题差不多,唯一一点不同在于除了第一次,你可以从n + 1的位置去使用传送器

思路(枚举 + 二分)

找到每个位置上花费最少的费用和若是第一次去该位置要花多少钱记录下来。
然后排序,求前缀和
枚举每个可以作为第一次去的位置,然后二分出最大可以去多少个传送器,若当前位置小于二分出的数量,则该位置上要减去最少费用加上第一次在这个位置需要的钱。
若当前位置大于等于二分出的位置,则将该位置作为前置条件,只需要加上第一次在这个位置的费用即可。
最后需要的传送器个数:若该位置小于二分出的位置,则就是l,否则需要加上前置也就是l + 1

void solve() {
	int n, c;
	cin >> n >> c;
	vector<pair<LL, LL>> a;
	for (int i = 1; i <= n; i ++) {
		int x;
		cin >> x;
		a.push_back({min(x + i, x + n - i + 1), x + i});
	}
	
	sort(a.begin(), a.end());
	
	vector<LL> sum(n + 1, 0);
	
	for (int i = 1; i <= n; i ++) {
		sum[i] = a[i - 1].first + sum[i - 1];
	}
	
	int ans = 0;
	
	for (int i = 0; i < n; i ++) {
		if (a[i].second <= c) {
			int l = 0, r = n, mid;
			while (l < r) {
				mid = (l + r + 1) >> 1;
				LL price = sum[mid];
				if (mid > i) {
					price -= a[i].first;
				}
				if (price + a[i].second <= c) {
					l = mid;
				} else r = mid - 1;
			}
			
			ans = max(ans, l + 1 - (l > i));
		}
	}
	cout << ans << endl;
}

\[\]

总结

本场没什么难度,思维都挺简单地,最难得也就是G2,但是也就是枚举+二分

标签:cout,int,void,Codeforces,cin,++,solve,2.3,Div
From: https://www.cnblogs.com/lbzbk/p/17092506.html

相关文章

  • Educational Codeforces Round 142 (Rated for Div. 2)(C,D)
    EducationalCodeforcesRound142(RatedforDiv.2)(C,D)CC这道题的大意是题目大意是给你一个任意的排序,我们要把这个排序通过任意个操作变成一个有序的排序操作是,选择......
  • Codeforces Round #838 (Div. 2)-D. GCD Queries-GCD、交互
    题目:https://codeforces.com/problemset/problem/1762/D有一个0~n-1的排列,你要在至多2n次询问中找到两个位置x,y,使得\(p_x,p_y\)至少有一者为0.每次询问可以问两个不同的i......
  • CodeForces - 234E Champions' League(模拟)
    Description: Intheautumnofthisyear,twoRussianteamscameintothegroupstageofthemostprestigiousfootballclubcompetitionintheworld—theUEFA......
  • CodeForces - 224D Two Strings
    Description:A subsequence oflength |x| ofstring s = s1s2... s|s| (where |s| isthelengthofstring s)isastring x = sk1sk2... sk|x| (1 ≤......
  • codeforces 1047C. Enlarge GCD(数学)
    题意:给出n个数,求出最少删除几个数可以扩大最大公因子。AC代码:#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<set>#include<map>#includ......
  • CodeForces 948A
    DescriptionBobisafarmer.Hehasalargepasturewithmanysheep.Recently,hehaslostsomeofthemduetowolfattacks.Hethusdecidedtoplacesomeshephe......
  • 算法-2023.2.3
    1.最小覆盖子串classSolution{publicStringminWindow(Strings,Stringt){HashMap<Character,Integer>map1=newHashMap<>();HashMap<......
  • 闲话 23.2.3
    闲话?咋这么晚了其实我写BM的原因是这样的我不知道想啥就想到了线性递推了然后想到线性递推就突然记起来zky代码里有个BM函数当时看没咋注意后来才发现不对劲......
  • 2023.2.3
    向上转型向下转型子类类型引用名=(子类类型)父类引用;(基本数据类型的强制转换)只能强转父类引用,不能强转父类对象;父类引用指向的必须是当前目标类型的对象;向下转型后,......
  • 【闲话】2023.2.3 k次加权组合数求和
    问题引入CodeForces-932ETeamWork给出\(n,k\),求:\[\sum_{i=1}^ni^k\dbinom{n}{i}\bmodp\]\(1\len\le10^9,1\lek\le5000,p=10^9+7\)\(k=0\)二项式定理:\[......