首页 > 其他分享 >AtCoder Beginner Contest 380 (A~E)题解

AtCoder Beginner Contest 380 (A~E)题解

时间:2024-11-17 23:19:02浏览次数:1  
标签:AtCoder insert int 题解 380 second erase mp first

A - 123233

遍历字符串统计出现次数即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, m, k;
int a[N];
signed main() {
	string s;
	cin >> s;
	map<char, int> mp;
	for (auto t : s) {
		mp[t]++;
	}
	if (mp['2'] == 2 && mp['1'] == 1 && mp['3'] == 3) {
		cout << "Yes\n";
	} else {
		cout << "No\n";
	}
}

B - Hurdle Parsing

直接计数,遇到 $ | $ 输出即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, m, k;
int a[N];
signed main() {
	string s;
	cin >> s;
	int cnt = 0, f = 0;
	for (int i = 0; i < s.size(); i++) {
		if (s[i] == '|') {
			if (f == 1)
				cout << cnt << ' ';
			cnt = 0;
			f = 1;
		}
		if (s[i] != '|') {
			cnt++;
		}
	}
}

C - Move Segment

题意是将第 $ k $ 个连续的字符 $ 1 $ 段与第 $ k-1 $个段合并。

用 $ vector $ 存储一下连续的每一段然后根据题目要求顺序即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, m, k;
int a[N];
signed main() {
	string s;
	cin >> n >> k;
	cin >> s;
	string now1 = "", now2 = "";
	vector<string> a;
	for (int i = 0; i < n; i++) {
		if (s[i] == '1') {
			now1 += s[i];
			if (now2.size() != 0) {
//				cout << now2 << '\n';
				a.push_back(now2);
				now2 = "";
			}
		}
		if (s[i] == '0') {
			now2 += s[i];

			if (now1.size() != 0) {
				a.push_back(now1);
//				cout << now1 << '\n';
				now1 = "";
			}
		}
	}
	if (now1.size())
		a.push_back(now1);
	if (now2.size())
		a.push_back(now2);
//	for (auto t : a) {
//		cout << t << ' ';
//	}
	cout << '\n';
	int cnt = 0, d1 = 0, d2 = 0;
	for (int i = 0; i < a.size(); i++) {
		if (a[i][0] == '1') {
			cnt++;
			if (cnt == k - 1) {
				d1 = i;
			}
			if (cnt == k) {
				d2 = i;
				for (int j = 0; j <= d1; j++) {
					cout << a[j];
				}
				cout << a[d2];
				for (int j = d1 + 1; j < a.size(); j++) {
					if (j != d2) {
						cout << a[j];
					}
				}
				return 0;
			}
		}
	}
}

D - Strange Mirroring

利用对称的思想,观察每次查询的第 $ k $ 个字符最初是由哪个字符演变过来的,并记录演变次数,根据次数判断字符大小写。可以观察发现,每次我们都可以通过对称使得字符串长度减少 $ n*2^x $ 的长度,该长度通过二分查找,多次缩短我们便能找到查询位置字符最初的字符。

时间复杂度:$ O(q*log k) $。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, m, k;
int a[N];
int b[100];
signed main() {
	string s;
	cin >> s;
	n = s.size();
	s = ' ' + s;
	int q;
	cin >> q;
	vector<int> a;
	int x = n;
	for (int i = 1; i <= 64; i++) {
		if (x > 1e18) break;
		a.push_back(x);
		x *= 2;
	}
	for (int i = 0; i < a.size(); i++) {
		b[i + 1] = a[i];
	}
	while (q--) {
		cin >> k;
		int d = 0;
		int cnt = 0;
		for (int i = 1; i <= 100; i++) {
			int x = lower_bound(b + 1, b + 1 + (int)a.size(), k) - b;
			x -= 1;
			k -= b[x];
//			cout << x << '\n';
			if (b[x] != 0)
				cnt++;
			if (k <= n) break;
		}
//		cout << k << '\n';
//		cout << cnt << '\n';
		char x = s[k];
		if (cnt % 2 == 0) {
			cout << x << ' ';
		} else {
			if (x >= 'a' && x <= 'z')
				cout << (char)(x - 32) << ' ';
			else
				cout << (char)(x + 32) << ' ';
		}
//		cout << '\n';

	}
}

E - 1D Bucket Tool

使用两个 $ set $ 维护 $ l $ 和 $ r $ 区间,用 $ set<pair<int,int>> $ 维护存在的颜色的区间,使用 $ map<pair<int,int>> $ 维护颜色区间的颜色。每次修改通过二分查找出 $ x $ 分类讨论所在区间段再根据左右区间段颜色 $ c $ ,判断是否需要合并区间,每次修改完成后更新 $ sum $ 数组的值,不断维护 $ stl $ 容器的值,注意不要出现越界的问题,思路不乱维护好就可以了。

真是一次酣畅淋漓的 $ set $ 练习

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int n, m, k;
int sum[N];
set<pair<int, int>> col;
set<int> sel, ser;
map<pair<int, int>, int> mp;
void work(pair<int, int> l, pair<int, int> b, pair<int, int> r, int x) {
	sel.erase(l.first), sel.erase(b.first), sel.erase(r.first);
	ser.erase(l.second), ser.erase(b.second), ser.erase(r.second);
	int a = mp[ {l.first, l.second}], bt = x, c = mp[ {r.first, r.second}];
	int be = mp[ {b.first, b.second}];
	sum[be] -= b.second - b.first + 1;
	sum[x] += b.second - b.first + 1;
	if (a == bt && bt == c) {
		pair<int, int> f = {l.first, r.second};
		mp.erase(b), mp.erase(l), mp.erase(r);
		mp[f] = x;
		col.erase(l), col.erase(r), col.erase(b);
		col.insert(f);
		sel.insert(l.first), ser.insert(r.second);
	} else if (a == bt) {
		pair<int, int> f = {l.first, b.second};
		mp.erase(b), mp.erase(l);
		col.erase(b), col.erase(l);
		mp[f] = x;
		col.insert(f);
		sel.insert(l.first), ser.insert(b.second);
		sel.insert(r.first), ser.insert(r.second);
	} else if (bt == c) {
		pair<int, int> f = {b.first, r.second};
		mp.erase(b), mp.erase(r);
		col.erase(b), col.erase(r);
		mp[f] = x;
		col.insert(f);
		sel.insert(b.first), ser.insert(r.second);
		sel.insert(l.first), ser.insert(l.second);
	} else {
		pair<int, int> f = {b.first, b.second};
		mp[f] = x;
		sel.insert(r.first), ser.insert(r.second);
		sel.insert(l.first), ser.insert(l.second);
		sel.insert(b.first), ser.insert(b.second);
	}
}
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		sel.insert(i), ser.insert(i);
		col.insert({i, i});
		mp[ {i, i}] = i;
		sum[i] += 1;
	}
	while (m--) {
		int op, x, c;
		cin >> op;
		if (op == 1) {
			cin >> x >> c;
			auto it1 = sel.lower_bound(x);
			auto it2 = ser.lower_bound(x);
			if (it1 == sel.end()) {
				it1 = --sel.end();
			}
			if (*it1 > x) it1--;
			auto it3 = col.lower_bound({*it1, *it2});
			pair<int, int> b = *it3, l, r;
			pair<int, int> ed = *--col.end(), be = *col.begin();
			if (b != ed) {
				it3++;
				auto t = col.lower_bound(*it3);
				it3--;
				r = *t;
			}
			if (b != be) {
				it3--;
				auto t = col.lower_bound(*it3);
				it3++;
				l = *t;
			}
			work(l, b, r, c);
		} else {
			cin >> c;
			cout << sum[c] << '\n';
		}
	}
}

标签:AtCoder,insert,int,题解,380,second,erase,mp,first
From: https://www.cnblogs.com/ZhangDT/p/18551376

相关文章

  • P10124 [USACO18OPEN] Family Tree B 题解
    思路这道题目很像找\(2\)头牛的最近公共祖先,即lca,但是并不用那么麻烦.因为数据很小,我们可以写一个山寨版的lca.具体如下.intmother(stringx,stringy){ intres=0; while(y!=""){//有名字的牛 if(x==y)returnres;//两头牛的名字相等,说明是同......
  • [AGC032B] Balanced Neighbors 题解
    考虑先写个暴力\(O(n2^m)\)的输出一下结果,看一下n=4,5,6的(尤其是n=6的)结果,尤其是每个点像其余哪几个点连边,然后就想到了构造方案。代码constintN=109;intn;inte[N][N];voidskymaths(){read(n);if(n%2==0){rep(i,1,n){......
  • 一些Leetcode关于双指针的简单题解
    26.删除有序数组中的重复项给你一个非严格递增排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。然后返回nums中唯一元素的个数。考虑nums的唯一元素的数量为k,你需要做以下事情确保......
  • [题解]AtCoder Beginner Contest 380(ABC380) A~F
    A-123233照题意统计即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings;map<char,int>ma;signedmain(){ cin>>s; for(chari:s)ma[i]++; if(ma['1']==1&&ma['2']==2&&ma['3']==3)co......
  • 【星航计划】2024.11 Div. 3 题解
    2024--星航计划--十一月份--基础算法A.分段每一段连续的\(1\)之间是独立的,我们只需要关心一段连续的1的结果。可以证明对于一段连续的\(1\),最优策略是将其划分成多个单独的\(1\)以及可能余下的连续两个\(1\)。对于\(k\)个连续的\(1\),如果\(k\)是奇数,......
  • 【学校训练记录】11月个人训练赛4个人题解
    A题意可以理解为在a,b的范围内如果一个数是某个整数的立方,求与其距离为k的范围内有几个整数的平方数,我们可以对于每个立方数求出其数量,注意边界问题#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;inta,b,k;voidsolve(){ cin>>a>>b>>k; in......
  • abc380 赛后总结
    菜菜菜,不是你怎么这么菜。A-C模拟即可。D正常的方法因为不管怎么粘合总是一个字符串在复制,所以我们只用考虑大小写问题。我们设字符串为\(A\),被反转大小写的字符串为\(B\),那么这个字符串会长这样:\(ABBABAABBAABABBA\cdots\),第一个\(A\)的位置是\(0\)的话,我们可以发现......
  • 【未完结】 AtCoder Beginner Contest 380 题解
    AtCoderBeginnerContest380Rated:\(770\)A-123233简单模拟B-HurdleParsing字符串模拟C-MoveSegment找到第\(k\)个块的下标,模拟。D-StrangeMirroringE-1DBucketToolF-ExchangeGameG-AnotherShuffleWindow......
  • 【AtCoder】Beginner Contest 378-E.Mod Sigma Problem
    题目链接ProblemStatementYouaregivenasequenceA=(A1......
  • 【AtCoder】Beginner Contest 378-F.Add One Edge 2
    [题目链接](F-AddOneEdge2(atcoder.jp))ProblemStatementYouaregivenatreewithNNNvertices.Thei......