藍橋杯 基礎訓練 完美的代價-----------------------------C語言——菜鳥級
阿新 • • 發佈:2019-01-03
/*問題描述
迴文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。
小龍龍認為迴文串才是完美的。現在給你一個串,它不一定是迴文的,
請你計算最少的交換次數使得該串變成一個完美的迴文串。
交換的定義是:交換兩個相鄰的字元
例如mamad
第一次交換 ad : mamda
第二次交換 md : madma
第三次交換 ma : madam (迴文!完美!)
輸入格式
第一行是一個整數N,表示接下來的字串的長度(N <= 8000)
第二行是一個字串,長度為N.只包含小寫字母
輸出格式
如果可能,輸出最少的交換次數。
否則輸出Impossible
樣例輸入
5
mamad
樣例輸出
3
思路: 用貪心,先保證能構 成迴文 由兩邊向中間查詢找 注意邊界情況 和特殊情況;
*/
#include<stdio.h>
#include <string.h>
int main()
{
char a[8005];//儲存字串
char b[8005];//用於判斷字串能否構成字串;
long long i,j,len,t=1,t1=0,sum=0;
scanf("%lld\n",&len);
for(i=0;i<len;i++)
{scanf("%c",&a[i]);
b[i]=a[i];
}
for(i=0;i<len-1;i++)
for(j=i+1;j<len;j++)
if (b[i]>b[j]){char c=b[i];b[i]=b[j];b[j]=c;}//按ASCII 值排序便於統計
for(i=0;i<len;i++)
if(b[i]==b[i+1]&&i<len){t++;}//統計每個相同字元的數量
else //用於判斷字串能否構成字串;
{ if(t%2==1)t1++;//若字元數量為奇數 且為奇數字符的種類大於等於2則不能構成迴文
if(t1>=2)break;
t=1 ; }
if(t1>=2)printf("Impossible\n");
else
{ i=0;//從第一位字元(0位)尋找對應字元;第一位對應最後一位 因此需找到與之匹配的字元換到最後一位
for(j=len-1;j>i;j--)//為次數最小則就近原則 從後向前查詢遇到的第一個匹配字元則通過相鄰字元交換
{ for(t=j;t>i;t--)//到對應位置 從匹配字元位到與查詢對應位置根據交換原則,交換後兩個交換位置
if(a[t]==a[i])//之間 的字元循序不變 可視為移位插入法(i 對應位置 是j 匹配字元 是t;則從t交換
{sum+=j-t;//到j 則需 j-t 次;
b[0]=a[t];
while(t<j)
{a[t]=a[t+1];t++;} //移位
a[j]=b[0];i++;break;//匹配字元插入對應位 然後i++尋找下一位
}
if(t==i&&j!=i){j++;char c=a[i];a[i]=a[i+1];a[i+1]=c;sum++;}//若查詢的對應字元為中心(奇數)字元
// 且不是查詢 中心(奇數)字元 的對應位
} // 則先將 中心(奇數)字元與非中心字元交換重找此對應位
printf("%lld\n",sum);
}
return 0;
}