ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Educational Codeforces Round 130 (Rated for Div. 2)

2022-07-17 11:31:32  阅读:147  来源: 互联网

标签:Educational Rated cout int LL Codeforces 查询 字符串 id


比赛链接:

https://codeforces.com/contest/1697

C. awoo's Favorite Problem

题意:

有一个字符串 \(s\),每次可以选择一个字串 "ab" 将其改为 "ba" 或者选择 "bc" 将其改为 "cb"。再给定一个字符串 \(t\),问是否可以通过若干次操作让 \(s\) 变成 \(t\)。

思路:

首先看两个字符串中 'a','b','c' 三个字符的数量是否相等,然后看两个操作的本质。
两个操作分别是让 \(a\) 向后移动,让 \(c\) 向前移动,可以发现 \(a\) 和 \(c\) 的相对位置是不会发生变化的,所以先将 \(b\) 从字符串中去掉,判断剩下的字符串是否相等。
接着看它们的相对位置是不是正确即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
void solve(){
	LL n;
	cin >> n;
	string s, t;
	cin >> s >> t;
	for (char c = 'a'; c <= 'c'; c ++ ){
		if (count(s.begin(), s.end(), c) != count(t.begin(), t.end(), c)){
			cout << "NO\n";
			return;
		}
	}
	vector <LL> ids, idt;
	for (int i = 0; i < n; i ++ ){
		if (s[i] != 'b'){
			ids.push_back(i);
		}
		if (t[i] != 'b'){
			idt.push_back(i);
		}
	}
	for (int i = 0; i < (int)ids.size(); i ++ ){
		if (s[ids[i]] != t[idt[i]]){
			cout << "NO\n";
			return;
		}
	}
	if (ids.size() != idt.size()){
		cout << "NO\n";
		return;
	}
	for (int i = 0; i < (int)ids.size(); i ++ ){
		if (s[ids[i]] == 'a'){
			if (ids[i] > idt[i]){
				cout << "NO\n";
				return;
			}
		}
		else if (s[ids[i]] == 'c'){
			if (ids[i] < idt[i]){
				cout << "NO\n";
				return;
			}
		}
	}
	cout << "YES\n";
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	LL T = 1;
	cin >> T;
	while(T -- ){
		solve();
	}
	return 0;
}

D. Guess The String

题意:

有一个长为 \(n\) 的字符串,通过查询去推出这个字符串是什么。
有两种查询方式:
第一种查询,输出 "? 1 p",会返回 \(p\) 这个位置的字符。该查询不能超过 26 次。
第二种查询,输出 "? 2 l r",会返回 \(l\) 到 \(r\) 区间中的字符的种类。该查询不能超过 6000 次。

思路:

首先第一种查询肯定是为了确定每一种字母的位置。可以通过 1000 次的第二种查询 + 不超过 26 次的第一种查询去确定每个字母第一次出现的位置。
只要每次查询 "? 2 1 i",询问 \([1, i]\) 区间中的字母种类,如果和 \([1, i - 1]\) 不一样的话,说明没出现过,那就通过第一种查询查一下。这里最多会用 1000 次第二种查询。
如果一样的话,说明该字母在之前出现过,用 \(id\) 数组去记录第 \(i\) 位之前每种字母最后出现的位置,那每次查询 "? 2 id i" 的时候,就可以知道第 \(i\) 个字母是之前的那一个字母了。这里最多用了 1000 * \(log_2^26\) 次第二种查询,不超过 5000。所以总的不超过 6000 次。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
char ask1(int x){
	cout << "? 1 " << x << "\n";
	char c;
	cin >> c;
	return c;
}
int ask2(int L, int R){
	cout << "? 2 " << L << " " << R << "\n";
	int t;
	cin >> t;
	return t;
}
int main(){
	LL n;
	cin >> n;
	LL sum = 0;
	vector <LL> id;
	vector <char> ans(n + 1);
	for (int i = 1; i <= n; i ++ ){
		int t = ask2(1, i);
		if (t > sum){
			char c = ask1(i);
			ans[i] = c;
			id.push_back(i);
			sum ++ ;
		}
		else{
			LL L = 0, R = id.size() - 1;
			while(L < R){
				LL mid = (L + R + 1) >> 1;
				int t = ask2(id[mid], i);
				if (t != (int)id.size() - mid + 1) L = mid;
				else R = mid - 1;
			}
			ans[i] = ans[id[L]];
			id[L] = i;
			sort(id.begin(), id.end());
		}
	}
	cout << "! ";
	for (int i = 1; i <= n; i ++ )
		cout << ans[i];
	cout << "\n";
	return 0;
}

标签:Educational,Rated,cout,int,LL,Codeforces,查询,字符串,id
来源: https://www.cnblogs.com/Hamine/p/16485473.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有