CodeForces Div124-1 hrbust 1474 哈理工oj 求字典序最大的子串【贪心】

求字典序最大的子串
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 44(27 users)Total Accepted: 36(27 users)Rating: Special Judge: No
Description
给定一串仅包含小写字母的字符串,找出字典序最大的子串。

对于字符串s, x和y是它的子串,x比y大,说明用C语言的字符串比较函数 strcmp(x, y) > 0。
如 s="ababba", x = "bbba", y="abaa" , x和y都是s的子串,x比y大。
Input
有多组测试数据,每组测试一行,仅包含一个由小写字母组成的字符串,长度小于等于10^6。
Output
对于每组测试数据,输出一行,为字典序最大的子串。
Sample Input
ababba
abbcbccacbbcbaaba
Sample Output
bbba
cccccbba
Source
CodeForces Div124-1

在求字典序最大的子串之前,我们需要了解一下比较字典序的strcmp函数的比较原理:
首先两个字符串比较字典序先比较第一个字母,如果第一个字母不同则按照a-z的顺序比较字典序,排序靠前的字典序更小。如果第一个字母相同递推到比较第二个字母,一直递推下去,直到遇到两个不同的字母或者是一方的长度已经遍历完毕,那么另一方的长度如果大于它,那么长度小的字典序更小。

贪心思路:

1、对于这个题目我们要求字典序最大的子串,那么我们就应该让子串的第一个字母最大。

2、让这个子串形成一个最长递减子序列【包括等于】。这里我们逆向实现。

逆向实现的思路:从主串的最后一个字母出发,向前遍历,如果前边的字母大于等于后边串中最大的字母,那么保存下来,最后逆序输出即可。

AC代码:

#include<stdio.h>
#include<string.h>
#include<cstring>
#include<iostream>
using namespace std;
char a[1000005];
int vis[1000005];
char ans[1000005];
int main()
{
    while(~scanf("%s",a))
    {
        int lena=strlen(a);
        memset(vis,0,sizeof(vis));
        int maxn=-0x3f3f3f3f;
        int pos;
        for(int i=0;i<lena;i++)
        {
            vis[i]=a[i]-'0';
            if(vis[i]>maxn)
            {
                maxn=vis[i];
                pos=i;
            }
        }
        int cont=0;
        int maxn2=-0x3f3f3f3f;
        for(int i=lena-1;i>=pos;i--)
        {
            if(vis[i]>=maxn2)
            {
                ans[cont]=a[i];
                cont++;
                maxn2=vis[i];
            }
        }
        ans[cont]='\0';
        for(int i=cont-1;i>=0;i--)
        {
            printf("%c",ans[i]);
        }
        printf("\n");
    }
}










  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值