码迷,mamicode.com
首页 > 其他好文 > 详细

完美的代价

时间:2020-01-23 00:19:19      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:结束   固定   字符串长度   代码   下标   word   cti   有一个   理解   

Description

回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。

小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。

交换的定义是:交换两个相邻的字符

例如: mamad

第一次交换 ad : mamda;

第二次交换 md : madma;

第三次交换 ma : madam (回文!完美!)

Input

第一行是一个整数N,表示接下来的字符串的长度(N ≤ 8000)。

第二行是一个字符串,长度为N.只包含小写字母。

Output

如果可能,输出最少的交换次数。

否则输出Impossible。

Sample Input

5
mamad

Sample Output

3
技术图片
 1 #include<stdio.h>
 2 int main(){
 3     int n;//代表要输入的字符长度 
 4     int flag=0;//用来标记是否出现了不能匹配的单个字符 
 5     int count=0;// 用来表示最少的交换次数 
 6     int j;//用来盛放n-1的值,仅是为了方便 
 7     char a[8005];//用来盛放字符串 
 8     char t;//用于字符的交换 
 9     scanf("%d",&n);//输入n 
10     scanf("%s",a);//输入字符串 
11     j=n-1;
12     for(int i=0;i<j;i++){//从下标为i的字符开始,到下标为【j-1】的字符结束,依次固定字符 
13         for(int k=j;k>=i;k--){//然后从下标为j的字符开始,到下标为i的结束(也就是从后往前)依次与固定的字符作比较 
14              if(i==k){//当固定的字符在字符串中没有找到能与它匹配的字符时 
15                 if(n%2==0||flag){//判断字符串的长度是不是偶数,或者flag的值是否为1 
16                     printf("Impossible");//如果满足这两个条件中的任意一个,那么这个字符不可能是回文串,输出Impossible结束即可 
17                     return 0;
18                 }
19                 flag=1;//如果字符串长度为奇数并且flag的值为0,就将flag赋值为1 ,代表出现了不能匹配的单个字符 
20                 count+=n/2-i;//count的值加上n/2-i ,n/2-i代表这个单个字符移到字符串中间位置的步数 
21             }
22             else if(a[i]==a[k]){// 如果两个字符相同,即固定的字符在后面找到了与它能匹配的字符 
23                 for(int b=k;b<j;b++){//将a[k]这个字符移到a[j]的位置 
24                     t=a[b];//交换过程 
25                     a[b]=a[b+1];
26                     a[b+1]=t;
27                     count++;//每交换一次,count自增1 
28                 }
29                 j--;//当固定的字符找到能与它匹配的字符时,j自减1 ,这一步很关键 
30                 break;// 当固定的字符找到能与它匹配的字符时,跳出第二层循环,第一层循环继续固定下一个字符 
31             }
32         }
33     }
34     printf("%d",count);//输出count的值 
35     return 0;
36 }
View Code

 


有几个问题详细解释一下:

 

一:  如果在回文串里有两个字符相同,我们就暂且称呼这两个字符相互匹配

 

二:  回文串的特点:如果回文串的长度为偶数,那么回文串里任何一个字符都能找到与之匹配的字符,如果回文串的长度为奇数,那么回文串里只能有一个字符是不能匹配的,大家仔细想一想这个特点。

 

三:关于代码中第 25 行为何要判断长度是否为偶数:当出现不能匹配的字符时,才会判断这个条件。因为回文串长度为偶数时,任何一个字符都是可匹配的,所以,当字符串中出现不可匹配的字符并且字符长度为偶数时,该字符串一定不是回文串。只有奇数长度的回文串才会出现不可匹配的字符,并且只能有一个不能匹配的字符。

 

四:关于代码中第 25 行为何要判断 flag 是否为 1:当出现不能匹配的字符时,才会判断这个条件。flag  为  1  代表字符串中已经出现了一个不可匹配的字符,当出现不能匹配的字符并且 flag 为 1 时,代表这个字符串里有两个不可匹配的字符,这与回文串的特点不符,所以该字符串一定不是回文串。

 五:j--与  i++几乎是同时发生的,我们可以这样理解,当字符串中的第一个字符与最后一个匹配好了的话,我们就暂时将他们舍弃,先不管他们,只看他们中间的字符就行,

 

 

 

 

用几个例子来理解一下过程:

 

样例一:mamad

 

1 首先在这里,代码中的 n 为 5,j 为 4,i 为 0,然后固定下标为 i 的字符,此时 i 为 0,即字符 m,然后从下标为 j 的字符开始,也就是从字符 d 开始,;依次向前

与 m 作比较字符 d 与字符 m 不相同,继续向前走,走到字符 a字符 a 与字符 m 仍然不相同,继续向前走,走到字符 m字符 m 与字符 m 相同,这时,将第二个 m 移到

下标为 j 的字符的地方,也就是字符 d 那里,首先 m 与 a 交换位置,count 自增 1,字符串变为 maamd,然后 m 与 d 交换位置,count 自增1,字符串变为 maadm,交

换步骤完成这时,j 会自减 1,j 变为 3,同时 break 跳出第二层循环,第一层循环的 i 自增 1,i 变为1

 

2 这时继续固定字符,固定下标为 i 的字符,此时 i 为 1,也就是字符 a,然后从下标为 j

 

的字符开始,此时 j 为 3,也就是从字符 d 开始,依次向前与 a 作比较

 

字符 d 与字符 a 不相同,继续向前走,走到字符 a

 

字符 a 与字符 a 相同,这时,将第二个 a 移到下标为 j 的地方,也就是字符 d 那里,字符 a

 

与字符 d 交换位置,count 自增 1,字符串变为 madam,交换步骤完成

 

这时,j 会自减 1,j 变成 2,同时 break 跳出第二层循环,第一层循环的 i 自增 1,i 变为

 

2

 

3 这时,继续执行第一层循环,发现 i=j=2,不符合循环条件,跳出循环,输出 count 的值,

 

count 共自增三次,所以输出 3.

 

样例二:accc

 

首先在这里,代码中的 n 为 4,j 为 3,i 为 0,然后固定下标为 i 的字符,此时 i 为 0,即

 

字符 a,然后从下标为 j 的字符开始,也就是从字符 c 开始,依次向前与 a 作比较,

 

字符 c 与字符 a 不相同,继续向前走,走到字符 c

 

字符 c 与字符 a 不相同,继续向前走,走到字符 c

 

字符 c 与字符 a 不相同,继续向前走,走到字符 a

 

这时,代码中 i 的值与 k 的值相同,字符 a 在字符串中找不到能与它匹配的字符,这时,判

 

断字符长度是否为偶数或者  flag  是否为  1,这时发现字符长度为偶数,那么该字符串一定

 

不是回文串。

 

样例三:abc

 

1 首先在这里,代码中的 n 为 3,j 为 2,i 为 0,然后固定下标为 i 的字符,此时 i 为 0,

 

即字符 a,然后从下标为 j 的字符开始,也就是从字符 c 开始,依次向前与 a 作比较

 

字符 c 与字符 a 不相同,继续向前走,走到字符 b

 

字符 b 与字符 a 不相同,继续向前走,走到字符 a

 

这时,发现字符 a 在字符串中找不到能与它匹配的字符,这时,判断字符长度是否为偶数或

 

着 flag 是否为 1,这时发现字符长度为奇数,并且 flag 为初始值 0,这时将 flag 赋值为

 

1,count+=   n/2-i,n/2-i 这里的值为 1,代表将字符 a 移到字符串中间所需要的步骤,注

 

意一下,这时并不用真的将字符 a 移到字符串中间,只需加上所需步骤即可

 

2 这时,i 自增 1,变为 1,j 仍为 2,然后继续固定下标为 i 的字符,即固定字符 b,从下

 

标为 j 的字符开始,也就是从字符 c 开始,依次向前与 b 作比较

 

字符 c 与字符 b 不相同,继续向前走,走到字符 b

 

这时,i 的值与 k 的值相同,判断字符长度是否为偶数或者 flag 是否为 1,发现字符长度为

 

奇数,flag 为 1,代表此时已经发现了两个不可匹配的字符,那么该字符串不可能为回文串。


完美的代价

标签:结束   固定   字符串长度   代码   下标   word   cti   有一个   理解   

原文地址:https://www.cnblogs.com/fate-/p/12229800.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!