1. 程式人生 > >藍橋杯 基礎訓練 完美的代價-----------------------------C語言——菜鳥級

藍橋杯 基礎訓練 完美的代價-----------------------------C語言——菜鳥級

/*問題描述
  迴文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。
小龍龍認為迴文串才是完美的。現在給你一個串,它不一定是迴文的,
請你計算最少的交換次數使得該串變成一個完美的迴文串。
  交換的定義是:交換兩個相鄰的字元
  例如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; }