zoukankan      html  css  js  c++  java
  • 常州模拟赛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;
    }
  • 相关阅读:
    CodeForces 1208 A. Boys and Girls 模拟序列
    CodeForces 1209 B. Jury Size 树状数组处理区间统计问题
    Linux环境进程间通信(转IBM)
    Qt(转IBM)
    POSIX 线程详解(转IBM)
    Perl 编程系列
    Socket in Linux(转IBM)
    Return to the Basic 限定符: const和volatile.
    SQA
    (C++)从本机获取WMI数据.
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7426798.html
Copyright © 2011-2022 走看看