以下の質問
回文文字列、同じことを読み取るために、右と右から左へ、左から読まれる特殊な文字列。
少し曇っては完璧回文文字列であると考えています。あなたはそれはあなたが交換の最小数を計算し、必ずしも回文ではなく、文字列を与えられているので、完全な回文文字列に文字列。
交換の定義は、2つの隣接する文字の交換
例えば、:mamad
第交換広告:mamda;
第二の交差がmdの:madma;
第交換MA:マダム(!!完全パリンドローム)
Input
最初のラインであります整数N、文字列(N≤8000)の次長さ。
2行目は、小文字を含む長さNの文字列です。
Output
可能であれば、交換の最小数の出力。
それ以外の場合は、出力不可能。
トピックのアイデア
- その後、1私たちの第一の基準としての文字、そしてこの手紙がある場合インポッシブルは直接リターンが存在しない場合は、フロントに戻ってから検索
- 2、我々は基準として第2文字で開始する場合、3番目の文字の参照文字の最後から二番目の文字から検索を開始
- 最初のN / 2個の参照文字が終了するまで3まで。
!!!
手紙は、この場合にはdaamm
、参照文字をdとした後インポッシブル、私達のリターンをDを検索していない、そして、その後、プログラムに問題がある、我々は標準の文字と次の文字、その後、再起動し、検索を交換する必要があります唯一の問題を解決します。
具体的な手順
#include <iostream>
#include <string>
using namespace std;
void swap(char &a,char &b){
char t;
t = a;
a = b;
b = t;
return;
}
int main()
{
int ans = 0;
int q;
// 测试数据集
string c = "dmmaa";
int len = c.length();
// cin >> len;
// cin >> c;
int flag=1;
int s[len] = {0};
// 开始遍历基准字母
for(int i=0;i<len/2;i++){
if(c[i]!=c[len-i-1]){
flag = 1;
// 发射一枚针从后向前搜索
for(int j=len-i-2;j!=i;j--){
// 找到了,开始不断的交换
if(c[j]==c[i]){
for(int k=j;k<len-i-1;k++){
swap(c[k],c[k+1]);
// cout << c[k] << " " << c[k+1] << endl;
ans++;
}
flag = 0;
break;
}
}
// 如果没有找到
if(flag){
// 如果情况特殊,我们需要将基准字母和下一个字母做一次交换,并重新开始搜索
if(len%2==1){
swap(c[i],c[i+1]);
ans++;
if(s[i]==0){
s[i]++;
i--;
continue;
}
}
cout << "impossible" << endl;
return 0;
}
}
}
// 全部基准字母都有,返回交换次数
cout << ans << endl;
return 0;
}