zoukankan      html  css  js  c++  java
  • 牛客练习赛36 A Rabbit的字符串(字符串最小表示法)

    链接:https://ac.nowcoder.com/acm/contest/328/A
    来源:牛客网

    题目描述

    Rabbit得到了一个字符串,她的好朋友xxx可以给这个字符串施加一次魔法。
    魔法可以选择字符串的任一位置,并将该位置后面的所有字符水平拼接到串首。
    例如:对于字符串abcde,可以通过施加魔法得到cdeab。
    如果xxx通过施加魔法将字符串的字典序变得严格比之前的小,那么他将拿走这一字符串。
    Rabbit想知道自己的字符串会不会被xxx拿走。

    输入描述:

    第一行一个整数n,表示字符串的长度。

    接下来一行一个长度为n的只由小写字母组成的字符串。

    输出描述:

    如果Rabbit的字符串会被xxx拿走,输出“YES”。
    否则输出“NO”。
    (不输出引号)
    示例1

    输入

    复制
    5
    cdeab

    输出

    复制
    YES

    说明

    xxx可以把e之后的部分“ab”放到串首,得到abcde,字典序比cdeab小,故将拿走字符串。
    示例2

    输入

    复制
    5
    abcde

    输出

    复制
    NO

    备注:

    1≤n≤100000

    字典序的说明:https://en.wikipedia.org/wiki/Alphabetical_order
     
    标答:
    可以用字符串最小表示法解决。
     
    #include <cstdio>
    #include <bits/stdc++.h>
    #include <map>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define mst(a,b) memset((a),(b),sizeof(a))
    #define rush() int T;scanf("%d",&T);while(T--)
    
    typedef long long ll;
    const int maxn = 100005;
    const ll INF = 1e18;
    const ll mod=1e9+7;
    const double eps = 1e-9;
    
    char s[maxn];
    char tmp[maxn];
    
    int find_min(char *s,int len) 
    {
        int i=0,j=1,k=0,t;
        while(i<len&&j<len&&k<len)
        {
            t=s[(i+k)>=len?i+k-len:i+k]-s[(j+k)>=len?j+k-len:j+k];
            if(t==0)k++;
            else
            {
                if(t>0) i+=k+1;
                else j+=k+1;
                if(i==j) ++j;
                k=0;
            }
        }
        return (i<j?i:j);
    }
    
    void get_temp(int len)    
    {
        int k=find_min(s,len);
        for(int i=0; i<len; i++)
        {
            tmp[i]=s[(i+k)%len];
        }
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        scanf("%s",s);
        get_temp(n);
        tmp[n]='';
        if(strcmp(s,tmp)==0) puts("NO");
        else puts("YES");
    }
    View Code

    不会证明。攒个模板吧。

    int find_min(char *s,int len) 
    {
        int i=0,j=1,k=0,t;
        while(i<len&&j<len&&k<len)
        {
            t=s[(i+k)>=len?i+k-len:i+k]-s[(j+k)>=len?j+k-len:j+k];
            if(t==0)k++;
            else
            {
                if(t>0) i+=k+1;
                else j+=k+1;
                if(i==j) ++j;
                k=0;
            }
        }
        return (i<j?i:j);
    }
    View Code
  • 相关阅读:
    UVA11300分金币
    hdu3987 最小割边数
    直线上的整点个数
    BZOJ 2818 Gcd
    服务器数据恢复成功案例+服务器数据恢复通用原理
    【转】Linux AIO机制
    如何更好地与人沟通?看完这本书,你也能成为沟通高手!
    “自我管理”是成功人士必备的能力,提高自我管理能力推荐你看这些书!
    能帮你提高沟通能力的十沟通类书籍推荐
    团队管理者必看的书籍推荐,团队管理的良方都在这本书里
  • 原文地址:https://www.cnblogs.com/acboyty/p/10246366.html
Copyright © 2011-2022 走看看