C.Hamiltonian Wall
思路:考察dp。 先遍历找出一个上下两格不同的一列, 在分别从两边向边缘处遍历。
1.若在后边还存在 B 但和上一处的 B 不相连----就是 w 和 B 连在一起。 则不成立。
2.通过dp 计算各处B的数量。
详细的见代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[200010];//代表各列B 的数量。
void solve()
{
int m;
cin>>m;
memset(f,0,sizeof f);
string s[2];
cin>>s[0];
cin>>s[1];
int x=-1,y=-1;
for (int i=0;i<m;i++){
if(s[0][i]!=s[1][i]) {
if(s[0][i]=='B') x=0,y=i;
else x=1,y=i;
break;
}
}
if(x==-1 && y==-1) {
cout<<"YES"<<endl;
return ;
}//如果整个序列中都没有B和 W这一列 则可直接成立
int flag=0,t;
t=x;
for (int i=0;i<m;i++){
if(i) f[i]=f[i-1];
if(s[0][i]=='B') f[i]++;
if(s[1][i]=='B') f[i]++;
}//使用dp计算各列的一个前缀B 数量。
for (int i=y;i>0;i--){
if(s[x][i-1]=='W') {
if(f[i-1]>0) flag=1;
break;
}
else {
if(s[!x][i-1]=='B'){
x=!x;
}
}
}//向左边遍历
x=t;
for (int i=y;i<m-1;i++){
if((s[x][i+1]=='W')){
if(f[m-1]-f[i]>0) {
flag=1;
}
break;
}
else {
if(s[!x][i+1]=='B'){
x=!x;
}
}
}
if(flag==1) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}//向右边遍历。
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}