C. awoo's Favorite Problem_思维+set
作者:互联网
题目大意
给字符串s和t。现有两种操作,操作1使“ab”变成“ba”,操作2使“bc”变成“cb”。问经过若干次操作后s有无可能变成t。
思路和代码
将两个字符串一位一位进行匹配。然后就有四种情况:
- s_i==t_i 则匹配
- s_i == 'a' and t_i == 'b' 则表明i位置的b需要从[i,n]中的某个位置(假设是j)移动而来。考虑要从j一路移到i,则表明[i,j]中没有字符c(不然就断掉了)。而可以贪心的想到,j位置就是[i,n]区间中字符b的第一次出现位置。
- (s_i == 'b' and t_i == 'c') 和上一种情况类似。
- else
那么考虑如何编码:
做三个set,表示abc三种字符在[i,n]区间中的下标序列。然后两个字符串一位一位的对齐匹配,出现不匹配情况就尝试去将ti移动到si位置。总体是一个模拟的思路。
string solve2(){
cin >> n ;
string s , t ;
cin >> s >> t ;
s = " " + s ;
t = " " + t ;
set<ll> idx[3] ;
rep(i , 1 , n)
idx[s[i] - 'a'].insert(i) ;
//[i,n]的abc三种字母的升序下标序列
rep(i , 1 , n){
// cout << i << "=>" << s << "\n" ;
if(s[i] == t[i]){//直接匹配
idx[s[i] - 'a'].erase(i) ;
continue ;
}
if(s[i] == 'a' && t[i] == 'b'){
//aaab 后面的b移到i位置
//baaa
if(!idx[1].size()) return "NO\n" ;//没有b可以换到i位置
int posb = *idx[1].begin() ;
int posc = *idx[2].begin() ;
if(idx[2].size() && posc < posb) return "NO\n" ;
idx[0].erase(i) ;
idx[1].erase(posb) ;
idx[0].insert(posb) ;
swap(s[i] , s[posb]) ;
// cout << i << " <- " << posb << "\n" ;
continue ;
}
if(s[i] == 'b' && t[i] == 'c'){
//bbbc
//cbbb
if(!idx[2].size()) return "NO\n" ;
int posc = *idx[2].begin() ;
int posa = *idx[0].begin() ;
if(idx[0].size() && posa < posc) return "NO\n" ;
idx[1].erase(i) ;
idx[2].erase(posc) ;
idx[1].insert(posc) ;
swap(s[i] , s[posc]) ;
continue ;
}
return "NO\n" ;
}
return "YES\n" ;
}
标签:字符,set,匹配,位置,Favorite,cin,awoo,字符串 来源: https://www.cnblogs.com/tyriis/p/16439394.html