• 883H


    题目链接:http://codeforces.com/problemset/problem/883/H

    题目大意:给一段长度为n的字符串s,想让你把s切成几段长度相同的回文串,可以改变s中字符的排列,最少可以出现切成几段。

    解题思路:看了大佬写的,自己思维还是有诸多不足,也学到了vector可以用pop_back()删除最后一个元素,还学到了处理字符数量的技巧。首先,每段回文串里肯定都有一个字符是单个的,假设每段回文串都没有字符是单个的,那说明可以合成一串,假设不成立。假设有的回文串中有字符是单个的,有的没有,那长度肯定是一奇一偶不符合题目每段长度都相同的要求,假设不成立。

         用vector<char>shuang,vector<char>dan分别统计出现两次和出现一次的字符。

         所以可以分为以下几步:

         ①计算每个字符出现次数,并判奇偶,如果是偶数个就拆分成多个数量为2的字符存入(比如‘c’出现4次,那就存入两次c)shuang。如果是奇数个,就先拿一个存入dan,再把剩下的拆分成多个数量为2的字符存入shuang。

         ②如果没有出现数量为奇数的字符,那就最少可以只有一个回文串,直接将s输出。

         ③出现数量为奇数的字符,如果shuang内的字符不能平分给dan内的字符,也就是不能形成长度相同的回文串,那就把双里的字符拆成两次放入dan中,使得shuang能被dan平分。然后直接输出所有回文串即可。

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 #include<cstdio>
     5 #include<vector>
     6 using namespace std;
     7 const int N=4e5+5;
     8 
     9 int cnt[300];
    10 char ans[N],s[N];
    11 vector<char>dan;
    12 vector<char>shuang;
    13 
    14 int main(){
    15     int n;
    16     scanf("%d",&n);
    17     scanf("%s",s);
    18     for(int i=0;i<n;i++){
    19         cnt[s[i]]++;
    20     }
    21     for(int i=0;i<=256;i++){
    22         if(cnt[i]){
    23             if(cnt[i]%2){
    24                 cnt[i]--;
    25                 dan.push_back(i);
    26             }
    27             while(cnt[i]){
    28                 cnt[i]-=2;
    29                 shuang.push_back(i);
    30             }
    31         }
    32     }
    33     if(dan.size()==0){
    34         for(int i=0;i<n/2;i++){
    35             ans[i]=ans[n-i-1]=shuang.back();
    36             shuang.pop_back();
    37         }
    38         ans[n]='';
    39         printf("1
    %s
    ",ans);
    40     }
    41     else{
    42         //用偶数单词凑成每段长度相同 
    43         while(shuang.size()%dan.size()){
    44             dan.push_back(shuang.back());
    45             dan.push_back(shuang.back());
    46             shuang.pop_back();
    47         }
    48         int len=n/dan.size();
    49         printf("%d
    ",dan.size());
    50         for(int i=0;i<dan.size();i++){
    51             ans[len/2]=dan[i];
    52             for(int j=0;j<len/2;j++){
    53                 ans[j]=ans[len-j-1]=shuang.back();
    54                 shuang.pop_back();
    55             }
    56             ans[len]='';
    57             printf("%s ",ans);
    58         }
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    学点 C 语言(39): 函数 使用函数的代价与内联函数(inline)
    学点 C 语言(35): 函数 递归
    学点 C 语言(34): 函数 关于变量(auto、static、register、extern、volatile、restrict)
    学点 C 语言(37): 函数 常量(const)参数
    带进度的文件复制 回复 "冷风无泪" 的问题
    如何把一个程序中 Edit 中的文本赋给另一个程序的 Edit ? 回复 "Disk_" 的问题
    学点 C 语言(32): 函数 返回值
    博客园电子期刊2011年12月刊发布啦
    上周热点回顾(12.261.1)
    上周热点回顾(1.21.8)
  • 原文地址:https://www.cnblogs.com/fu3638/p/7712865.html
Copyright © 2020-2023  润新知