Educational Codeforces Round 130 (Rated for Div. 2)
作者:互联网
比赛链接:
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