codeforce-600C. Make Palindrome(贪心)

http://codeforces.com/problemset/problem/600/C

题意:给你一个小写字母组成的英文串,将它转换为回文串,要求,改变的字母的个数最小,移动字母不算改变字母。

所得的串字典序是最小的。最后输出所得到的串。

思路:要求改变的字母数最小那么用贪心的思想,就把原来的字母尽可能多的填入要求的串中。

首先,先把原串中的字母统计出来,开个数组存对应的字符的个数,然后从‘a’开始循环,如果对应字母的个数大于1;

如果是偶数个的话,就在所求串两端一边加一个,可以正好加完,若是奇数个的话那么按这样的操作,最后就剩下一个,那么把它加入队列。

最后操作队列中的单个的,然后补一个加到串的两端,直到串被补满。

然后再对串的一半排下序就可以了。

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 int cmp(const void*p,const void*q);
  6 char a[100005*2];
  7 char b[100005*2];
  8 char c[100005*2];
  9 char bb[100005*2];
 10 int aa[26];
 11 #include<queue>
 12 using namespace std;
 13 int main(void)
 14 {
 15     int n,i,j,k,p,q,l,z;
 16     while(scanf("%s",a)!=EOF)
 17     {
 18         queue<int>que;
 19         z=0;
 20         memset(aa,0,sizeof(aa));
 21         l=strlen(a);
 22         for(i=0; i<l; i++)//统计对应的字母有多少个
 23         {
 24             aa[a[i]-‘a‘]++;
 25         }
 26         int t=0;
 27         for(i=0; i<26; i++)
 28         {
 29             if(aa[i]!=0)
 30             {
 31                 if(aa[i]>=2)//大于2的先加在串的两端
 32                 {
 33                     while(aa[i]>1)
 34                     {
 35                         aa[i]-=2;
 36                         a[t]=i+‘a‘;
 37                         a[l-1-t]=i+‘a‘;
 38                         t++;
 39                         z+=2;
 40                     }
 41                 }
 42                 if(aa[i]==1) que.push(i);//剩下1的入队
 43
 44             }
 45
 46
 47         }
 48         while(!que.empty())
 49         {
 50             int f=que.front();
 51             que.pop();
 52             if(z>=l)
 53             {
 54                 break;
 55             }
 56             while(aa[f]>0)
 57             {
 58                 aa[f]-=2;
 59                 a[t]=f+‘a‘;
 60                 a[l-1-t]=f+‘a‘;
 61                 t++;
 62                 z+=2;
 63                 if(z>l)
 64                 {
 65                     break;
 66                 }
 67             }
 68             if(z>=l)//当满了就跳出
 69             {
 70                 break;
 71             }
 72         }
 73         int uu;
 74         if(l%2==0)//找串的一半(分奇数偶数讨论)
 75         {
 76             uu=l/2;
 77         }
 78         else uu=(l-1)/2;
 79         for(i=0; i<uu; i++)
 80         {
 81             b[i]=a[i];
 82         }
 83         qsort(b,uu,sizeof(char),cmp);//对串的一半排序
 84         for(i=0; i<uu; i++)
 85         {
 86             printf("%c",b[i]);
 87         }
 88         if(l%2==1)
 89         {
 90             printf("%c",a[(l)/2]);
 91         }
 92         for(i=uu-1; i>=0; i--)
 93         {
 94             printf("%c",b[i]);
 95         }
 96         printf("\n");
 97
 98     }
 99     return 0;
100 }
101 int cmp(const void*p,const void*q)
102 {
103     char *w=(char*)p;
104     char *u=(char*)q;
105     return (*w-‘a‘)-(*u-‘a‘);
106 }
时间: 2024-10-14 00:05:34

codeforce-600C. Make Palindrome(贪心)的相关文章

CodeForces - 748D Santa Claus and a Palindrome (贪心+构造)

题意:给定k个长度为n的字符串,每个字符串有一个魅力值ai,在k个字符串中选取字符串组成回文串,使得组成的回文串魅力值最大. 分析: 1.若某字符串不是回文串a,但有与之对称的串b,将串a和串b所有的魅力值分别从大到小排序后,若两者之和大于0,则可以放在回文串的两边. 2.若某字符串是回文串,将其魅力值从大到小排序后,两两依次分析:(mid---可能放在回文串中间的串的最大魅力值) (1)若两个数都是正的,那么就将其放在两边,并将结果计入ans.(ans---回文串两边的串的魅力值之和) (2)

2017-5-22-Train:Educational Codeforces Round 2

B. Queries about less or equal elements(二分) You are given two arrays of integers a and b. For each element of the second array b**j you should find the number of elements in array athat are less than or equal to the value b**j. Input The first line c

Codeforces 486C Palindrome Transformation(贪心)

题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N,指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:其实只要是对称位置不相同的,那么指针肯定要先移动到这里,修改字符只需要考虑两种方向哪种更优即 可.然后将所有需要到达的位置跳出来,贪心处理. #include <cstdio> #include <cstring> #include <cstdlib> #include <vec

贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

题目传送门 1 /* 2 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-3 9:14:02 7 File Name :B.cpp 8 *************************************************/ 9 10 #include

codeforce 985C Liebig&#39;s Barrels(贪心+思维)

Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You have m?=?n·k wooden staves. The i-th stave has length ai. You have to assemble n barrels consisting of k staves each, y

codeforce Gym 100685E Epic Fail of a Genie(贪心)

题意:给出一堆元素,求一个子集,使子集的乘积最大,如有多个,应该使子集元素个数尽量小. 题解:贪心,如果有乘积大于1的正数,那么是一定要选的,注意负数也可能凑出大于1的正数,那么将绝对值大于1的负数两两配对,如果还剩下一个,那么在判断一下,那个负数和比它小的最小负数的乘积是否大于1,如果是那么就选这两个.把所有可能凑成大于1的数选完以后,剩下的数一定比1小,那么就不选. 如果无法凑出大于1的数,那么再分类讨论一下. 挺容易写错... #include<bits/stdc++.h> using

codeforce 448C Painting Fence (贪心)

原题地址:http://codeforces.com/problemset/problem/448/C 题意: 略 题解 略 #include<bits/stdc++.h> #define clr(x,y) memset((x),(y),sizeof(x)) using namespace std; typedef long long LL; const int maxn=5000; int A[maxn+5]; int d[maxn+5][20]; void rmq_init(int A[]

Codeforce 588A - Duff and Meat (贪心)

Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day, she needs to eat exactly ai kilograms of meat. There is a big shop uptown and Malek wants to buy meat for her from there. In i-th day, they sell mea

CodeForce 508C Anya and Ghosts (贪心+模拟)

题目大意:有m个时刻,在第i时刻即wi秒的时候需要保持有r根蜡烛亮着,每根蜡烛维持的时间为t秒,点一根蜡烛需要1秒. 注意:一根蜡烛亮的时间为下一秒开始.并且一开始是可以事先准备蜡烛的. 想法:利用了优先队列,维护r根蜡烛,每次wi秒,它需要开始点蜡烛的最晚时间为wi-t,如果不够这个时间,那么在最晚结束点蜡烛的时间wi-1开始补上. 感谢阿扎夫人提供的思维题. AC代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include&