/问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。
小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,
请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如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];
}
<span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator"><</span>len<span class="token number">-1</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token keyword">for</span><span class="token punctuation">(</span>j<span class="token operator">=</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>j<span class="token operator"><</span>len<span class="token punctuation">;</span>j<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>b<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">></span>b<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">char</span> c<span class="token operator">=</span>b<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>b<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span>b<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span>b<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token operator">=</span>c<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//按ASCII 值排序便于统计 </span>
<span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator"><</span>len<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>b<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">==</span>b<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">&&</span>i<span class="token operator"><</span>len<span class="token punctuation">)</span><span class="token punctuation">{</span>t<span class="token operator">++</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//统计每个相同字符的数量 </span>
<span class="token keyword">else</span> <span class="token comment" spellcheck="true">//用于判断字符串能否构成字符串;</span>
<span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span>t<span class="token operator">%</span><span class="token number">2</span><span class="token operator">==</span><span class="token number">1</span><span class="token punctuation">)</span>t1<span class="token operator">++</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//若字符数量为奇数 且为奇数字符的种类大于等于2则不能构成回文 </span>
<span class="token keyword">if</span><span class="token punctuation">(</span>t1<span class="token operator">>=</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token keyword">break</span><span class="token punctuation">;</span>
t<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>t1<span class="token operator">>=</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Impossible\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">else</span>
<span class="token punctuation">{</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//从第一位字符(0位)寻找对应字符;第一位对应最后一位 因此需找到与之匹配的字符换到最后一位 </span>
<span class="token keyword">for</span><span class="token punctuation">(</span>j<span class="token operator">=</span>len<span class="token number">-1</span><span class="token punctuation">;</span>j<span class="token operator">></span>i<span class="token punctuation">;</span>j<span class="token operator">--</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">//为次数最小则就近原则 从后向前查找遇到的第一个匹配字符则通过相邻字符交换 </span>
<span class="token punctuation">{</span> <span class="token keyword">for</span><span class="token punctuation">(</span>t<span class="token operator">=</span>j<span class="token punctuation">;</span>t<span class="token operator">></span>i<span class="token punctuation">;</span>t<span class="token operator">--</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">//到对应位置 从匹配字符位到与查找对应位置根据交换原则,交换后两个交换位置 </span>
<span class="token keyword">if</span><span class="token punctuation">(</span>a<span class="token punctuation">[</span>t<span class="token punctuation">]</span><span class="token operator">==</span>a<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">//之间 的字符循序不变 可视为移位插入法(i 对应位置 是j 匹配字符 是t;则从t交换 </span>
<span class="token punctuation">{</span>sum<span class="token operator">+</span><span class="token operator">=</span>j<span class="token operator">-</span>t<span class="token punctuation">;</span><span class="token comment" spellcheck="true">//到j 则需 j-t 次; </span>
b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">=</span>a<span class="token punctuation">[</span>t<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">while</span><span class="token punctuation">(</span>t<span class="token operator"><</span>j<span class="token punctuation">)</span>
<span class="token punctuation">{</span>a<span class="token punctuation">[</span>t<span class="token punctuation">]</span><span class="token operator">=</span>a<span class="token punctuation">[</span>t<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>t<span class="token operator">++</span><span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token comment" spellcheck="true">//移位 </span>
a<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token operator">=</span>b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//匹配字符插入对应位 然后i++寻找下一位 </span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>t<span class="token operator">==</span>i<span class="token operator">&&</span>j<span class="token operator">!=</span>i<span class="token punctuation">)</span><span class="token punctuation">{</span>j<span class="token operator">++</span><span class="token punctuation">;</span><span class="token keyword">char</span> c<span class="token operator">=</span>a<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>a<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span>a<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a<span class="token punctuation">[</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">=</span>c<span class="token punctuation">;</span>sum<span class="token operator">++</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//若查找的对应字符为中心(奇数)字符 </span>
<span class="token comment" spellcheck="true">// 且不是查找 中心(奇数)字符 的对应位 </span>
<span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 则先将 中心(奇数)字符与非中心字符交换重找此对应位 </span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%lld\n"</span><span class="token punctuation">,</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
return 0;
}