标题:[求助]有一个长度为n的字符串s,你可以删除其中的m个字符,使剩余字符串的字 ...
只看楼主
Sky_
Rank: 2
等 级:论坛游民
帖 子:38
专家分:10
注 册:2019-12-17
结帖率:100%
已结贴  问题点数:5 回复次数:8 
[求助]有一个长度为n的字符串s,你可以删除其中的m个字符,使剩余字符串的字典序最小,输出这个字符串。
有一个长度为n的字符串s,你可以删除其中的m个字符,使剩余字符串的字典序最小,输出这个字符串。

输入
输入的第一行有一个整数T,接下来T组,每组第一行有2个整数n,m,第二行有一个字符串s。
1≤T≤5,1≤m,n≤105,s只包含小写英文字母。
输出
对于每组测试数据,输出一行,一个字符串,由字符串s删除m个字母后得到。
样例输入
2
5 2
abcab
10 4
lkqijxsnny
样例输出
aab
ijsnny
**********************************************
小白在线求解答
搜索更多相关主题的帖子: 删除 字符串 输出 字符 最小 
2019-12-17 20:37
D2284581470
Rank: 3Rank: 3
来 自:沈阳
等 级:论坛游侠
威 望:2
帖 子:169
专家分:147
注 册:2019-12-8
得分:0 
虽然我努力的帮你看,但我现在还是不懂
2019-12-17 20:56
bcbbcclbbc
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:11
帖 子:194
专家分:528
注 册:2019-8-15
得分:0 
解答什么,你那里不懂,请陈述,光贴题目,无法得知你的疑问
2019-12-18 10:11
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:1 
伪代码大约是
foo( s, n, m )
{
    m = 最小值(n,m)
    if( m == 0 )
        return s;

    minchar = 在 s 的前 m+1 个字符中的最小值
    因为 s 的前 m+1 个字符中的可能有多个同时最小
    所以得递归调用 foo( s+i, n-i, m-i ),其中 i 是最小字符的下标
    选出其中最小的那个
}
2019-12-18 11:14
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:4 
手上没有编译器,用 https:// 编译了一下,没法保证正确,仅供参考

程序代码:
#include <stdio.h>
#include <string.h>

void foo( char* s, unsigned n, unsigned m )
{
    m = m<=n?m:n;
    if( m == 0 )
        return;

    char minchar = s[0];
    for( unsigned i=1; i!=m+1; ++i )
        minchar = minchar<=s[i]?minchar:s[i];

    char s_min[106];
    strcpy( s_min, s );
    for( unsigned i=0; i!=m+1; ++i )
    {
        if( minchar != s[i] )
            continue;

        char s2[106];
        strcpy( s2, s+i );
        foo( s2+1, n-i-1, m-i );
        if( strcmp(s2,s_min) < 0 )
            strcpy( s_min, s2 );
    }
    strcpy( s, s_min );
}

int main( void )
{
    unsigned t;
    scanf( "%u", &t );
    while( t-- )
    {
        unsigned n, m; char s[106];
        scanf( "%u%u%s", &n, &m, s );
        foo( s, n, m );
        puts( s );
    }
}

收到的鲜花
  • Sky_2019-12-18 20:08 送鲜花  1朵   附言:谢谢大佬解答
2019-12-18 13:16
Sky_
Rank: 2
等 级:论坛游民
帖 子:38
专家分:10
注 册:2019-12-17
得分:0 
回复 5楼 rjsp
谢谢大佬解答,不过提交的时候显示运行错误
还有,目前还有点懵,我会再仔细理解一下你的代码思路
谢谢大佬啦

[此贴子已经被作者于2019-12-18 20:09编辑过]

2019-12-18 20:07
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
以下是引用Sky_在2019-12-18 20:07:24的发言:

谢谢大佬解答,不过提交的时候显示运行错误
还有,目前还有点懵,我会再仔细理解一下你的代码思路
谢谢大佬啦
要么一个个的删除,遍历,如果当前字符大于下一个字符,那就将当前字符删除;每次删除一个后,回退一格从新开始。
2019-12-19 08:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 6楼 Sky_
试试吧,不行我再改
程序代码:
#include <stdio.h>
#include <string.h>

void foo( char* s, unsigned n, unsigned m )
{
    m = m<=n?m:n;

    for( size_t i=0; i!=n && m!=0; )
    {
        if( s[i] > s[i+1] )
        {
            memmove( s+i, s+i+1, n-i );
            --m, --n;
            if( i > 0 )
                --i;
        }
        else
            ++i;
    }
}

int main( void )
{
    unsigned t;
    scanf( "%u", &t );
    while( t-- )
    {
        unsigned n, m; char s[106];
        scanf( "%u%u%s", &n, &m, s );
        foo( s, n, m );
        puts( s );
    }
}

2019-12-19 09:07
Sky_
Rank: 2
等 级:论坛游民
帖 子:38
专家分:10
注 册:2019-12-17
得分:0 
回复 8楼 rjsp
答案正确了
跪谢大佬
2019-12-19 14:20



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-498468-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.218088 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved