常州模拟赛d4t3 字符串划分

题目描述

给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母

都不相同,并且希望分的段数尽量少。

然后,把这些小段按字典序排序后输出,中间由一个空格分隔。

例如:字符串 ”nnsmpmn”,最少分成 3 小段:”n”,”nsmp”,”mn”。

排序后输出:mn n nsmp

注意,有时候符合上面要求的方案可能有多个,就要输出排序后字典序最小的那个。

例如:字符串 ”aba” 可以有 2 种划分:a/ba 和 ab/a,排序后分别是:”a ba” 和 ”a ab”。

应该输出:a ab

输入输出格式

输入格式:

 

第一行包含 1 个正整数 k,表示有 k 组任务。

之后 k 行每行包含 1 个由小写字母组成的字符串 S。

 

输出格式:

 

共 k 行每行表示一个字符串的拆分方案。

 

输入输出样例

输入样例#1:
4
facetiously
aaaaa
aba
babb
输出样例#1:
facetiously
a a a a a
a ab
ab b b

说明

对于 30% 的数据:|S| ≤ 10; 对于 100% 的数据:k ≤ 10,|S| ≤ 50。

分析:细节题害死人QAQ.

      显然这是一道dp题,设f[i]为1~i位的最优结果,要记录一个二元组:分了多少个、分的字符串是啥,然后f[i] = min{f[j] + t},这个加法和min要我们自己来定义.总之就是细节题.

      以后不要轻易用string了,在类里面开一个string数组总是报错.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <cmath>

using namespace std;

int k;
bool vis[300];
char S[60];

struct node
{
    int tot;
    char ss[60];
};

struct node2
{
    int cnt;
    node s[60];
}f[600];

bool cmp2(node a, node b)
{
    for (int i = 1; i <= min(a.tot, b.tot); i++)
    {
        if (a.ss[i] != b.ss[i])
            return a.ss[i] < b.ss[i];
    }
    return a.tot < b.tot;
}

bool cmp(node2 a, node2 b)
{
    if (a.cnt != b.cnt)
        return a.cnt < b.cnt;
    for (int i = 1; i <= a.cnt; i++)
        return cmp2(a.s[i],b.s[i]);
}

int main()
{
    scanf("%d", &k);
    while (k--)
    {
        scanf("%s", S + 1);
        int sizee = strlen(S + 1);
        for (int i = 1; i <= sizee; i++)
            f[i].cnt = sizee + 1;
        for (int i = 1; i <= sizee; i++)
        {
            memset(vis, false, sizeof(vis));
            for (int j = i - 1; j >= 0; j--)
            {

                if (vis[S[j + 1] - 'a'])
                    break;
                vis[S[j + 1] - 'a'] = 1;
                node2 t = f[j];
                t.cnt++;
                for (int k = j + 1; k <= i; k++)
                {
                    t.s[t.cnt].tot++;
                    t.s[t.cnt].ss[k - j] = S[k];
                }
                sort(t.s + 1, t.s + 1 + t.cnt, cmp2);
                if (cmp(t, f[i]))
                    f[i] = t;
            }
        }
        for (int i = 1; i <= f[sizee].cnt; i++)
        {
            for (int j = 1; j <= f[sizee].s[i].tot; j++)
                cout << f[sizee].s[i].ss[j];
            printf(" ");
        }
        cout << endl;

    }

    return 0;
}

 

posted @ 2017-08-25 10:31  zbtrs  阅读(461)  评论(1编辑  收藏  举报