リンク:
トピック:2つの文字列を取得するには、任意の長さの文字列に対してフリップ操作を実行し(lenは各操作に対して長さlenの範囲を選択する必要があります)、2つの文字列ができるかどうかを尋ねます同じになる
最初に、たとえば2つの隣接する文字の交換と見なすことができる間隔を反転し、反転が成功するまでスワップを続けます。
abcde-> abced-> abecd-> aebcd-> eabcd
eabcd-> eabdc-> eadbc-> edabc
edabc-> edacb-> edcab
edcab-> edcba
EDCBA
バブルソートに似ています
この質問は、次の3つの状況に分けられます。
1. 2つの文字列に異なる文字がある場合、または同じ文字の数が異なる場合、それはnoでなければなりません。
2. SとTの文字列。SまたはTに2度以上現れる文字がある場合、きっと、
2つのaaがSに現れると仮定すると、交換中に、Sのaaは常に交換され、TのTはバブルソートに似ており、最終的にはSに等しくなる可能性があります。
3.この状況は、逆順ペア(逆順ペア:1≤i <j≤nおよびA [i]> A [j]である正の整数i、jがある場合、<A [i]、 A [j]>この順序付きペアは、Aの反転ペアと呼ばれます
(逆順番号とも呼ばれます)
最初にSを昇順に変更する方法を考え、同時にTの2つの隣接する文字をランダムに選択し、これらの2つを毎回交換します。この数がxであると仮定すると、このステップのステップ数はSの逆順ペアの数に依存します。
その後、Tを昇順に変更します。Tの逆順ペアの数がyであると仮定すると、このステップで必要なステップ数はy + 1またはy-1(xは奇数)、y(xは偶数)に等しくなります。
xが奇数の場合、Sが「Tに任意に隣接する2つの文字を選択し、毎回これら2つを交換する」操作でソートされた後、Tの逆のペアは明らかに1つずつ増加または減少します。
また、xが偶数の場合、数値は変化せず、これらの操作もSで実行する必要があります(隣接する2つの文字を任意に選択して、これら2つを毎回交換します)。x+ yが偶数であることがわかります(同じまたは奇数または偶数) )上記のステップを実行できます。それ以外の場合、一方が昇順の場合、もう一方の逆順ペアは1になります。
もちろん、最初に2つのストリングの逆の順序でパリティーの数が異なる場合、それは不可能です。
コード:(これをお気に入りに追加)
#include <bits / stdc ++。h> 名前空間stdを使用します。 const int maxn = 3e5 + 10; int n; 文字列s、t、S、T; int cnt(string s)//逆対数 { int num = 0; for(int i = 0; i <s.size(); i ++) for(int j = 0; j <i; j ++) if(s [j]> s [i]) num ++; numを返します。 } void solve() { cin >> n >> s >> t; S = s、T = t; sort(S.begin()、S.end()); sort(T.begin()、T.end()); for(int i = 0; i <n; i ++)// 1、 { if(S [i]!= T [i]) { puts( "いいえ\ n"); 戻る; } } for(int i = 1; i <n; i ++)// 2、 { if(S [i] == S [i-1] || T [i] == T [i-1]) { puts( "はい\ n"); 戻る; } } if(cnt(s)%2 == cnt(t)%2)// 3番目のケース puts( "はい\ n"); そうしないと puts( "いいえ\ n"); 戻る; } int main() { int t; cin >> t; while(t--) 解決する(); 0を返します。
}