基础训练 完美的代价(贪心算法)

来源:互联网 发布:淘宝卖家账号多少钱 编辑:程序博客网 时间:2024/04/30 18:49
问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出
3


贪心算法思想:
    目的就是选择当前步骤的最优解,在本题中也就是找到能够与之相匹配的字符。然后,进行交换,直至达到目标要求。


题目分析:
    在本题中,基本上可以分为两步走. 
  首先,处理所有不能够配对的字符,就是impossible的情况
  其次,处理剩下匹配的字符,其中,匹配的字符要移动到目标点的次数等价于j-t
(其中,j是未匹配字符的最右边的下标,t是当前匹配到的字符下标)。

用样例来讲,  
起始状态:
 0   1  2  3  4
mamad
 i            j

 按照题目分析原则:第一次的移动次数为:j-t=2次 

 0   1  2  3  4
mamad
 i      t     j     (其中,t为匹配到的字符下标)

同理,按照以上步骤,第二次移动的次数为:j-t=1次

0   1  2  3  4
maa
d
m
    i t   j    (j为当前最右边未匹配字符的下标)


因此,总的移动次数是2+1=3次  

0   1  2  3  4
m  a  d
a
m
      ij  




#include <stdio.h>#include <string.h>#define N 8000int main(void){int n;scanf("%d",&n);char a[N];scanf("%s",a);int i,j,t,l,p;j=n-1;int flag=0;int step=0;for(i=0;i<j;i++){t=j;//查找匹配的字符 while(a[i]!=a[t]){t--;}char temp;if(i==t){//如果为单个字符 flag++;if(n%2==0||flag>1){printf("Impossible");return 0;}step+=n/2-i;continue;//如果不加该语句,则单个字符也会执行下面的if语句a[i]==a[t] && t==i }//如果找到相匹配的两个数 if(a[i]=a[t]){step+=j-t;temp=a[t];for(l=t;l<j;l++){a[l]=a[l+1];}a[l]=temp;j--;}}printf("%d",step);return 0;}

详细记录
评测点序号评测结果得分CPU使用内存使用下载评测数据1正确10.000ms1.601MB输入 输出2正确10.0015ms1.597MB输入 输出3正确10.000ms1.601MB输入 输出4正确10.000ms1.597MB输入 输出5正确10.000ms1.597MB输入 输出6正确10.000ms1.597MB输入 输出7正确10.000ms1.597MB输入 输出8正确10.000ms1.597MB输入 输出9正确10.0015ms1.597MB输入 输出10正确10.000ms1.597MB输入 输出




0 0
原创粉丝点击