• 最小表示法


    http://www.fjutacm.com/Problem.jsp?pid=2411

    看到这题,我第一反应简单啊,刷刷刷把代码敲好交了一发

    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char s1[200000],s2[200000],s3[200000];
        int l,k;
        while(~scanf("%s",s1)){
            k=0;
            l=strlen(s1);
            strcpy(s3,s1);
            strcpy(s2,s1);
            strcat(s1,s2);
            while(strcmp(s3,s2)>=0){
                k++;
                for(int i=0;i<l;i++){
                    s3[i]=s1[i+k];
                }
            }
            puts(s3);
        }
        return 0;
    }

    不就比较字典序嘛,一个strcmp就解决了,很快啊

    然后果不其然

    然后寻找大佬帮助,大佬的思路如下:

    1.双指针i,j;

    2.通过"把已经比较过相等的字符跳过,从最后一个相等的字符的下一个字符开始比较字典序。"的方法降低时间复杂度;

    3.然后就是i+k和j+k的三种情况,相等小于大于分别处理;

    4.注意事项:i+k要取模防止溢出;i+k和j+k不相等时k=0;i和j相等时i++或者j++,要使它们指向两个不同的位置;

    5.最后取i和j里小的那一个。

    放代码:

    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char s[200005];
        int i,j,l,k,x;
        while(~scanf("%s",s)){
            i=0,j=1,k=0;
            l=strlen(s);
            while(i<l&&j<l&&k<l){
                if(s[(i+k)%l]==s[(j+k)%l])
                k++;
                else if(s[(i+k)%l]<s[(j+k)%l]){
                    j=j+k+1;
                    if(i==j)
                    j++;//i和j要指向不同位置
                    k=0;//k要重置为0
                }
                else if(s[(i+k)%l]>s[(j+k)%l]){
                    i=i+k+1;
                    if(i==j)
                    i++;
                    k=0;            }
            }
            if(i<j)
            x=i;
            else
            x=j;
            for(int i=0;i<l;i++){
                printf("%c",s[(i+x)%l]);
            }
            printf("
    ");
        }
        return 0;
    }

    PS:感谢大佬友情提示!

    EOF

  • 相关阅读:
    I/O性能优化
    磁盘性能指标
    磁盘I/O工作原理
    文件系统工作原理
    Linux命令行工具之free命令
    内存性能优化
    内存工作原理
    内存中的Buffer和Cache的区别
    proc文件系统
    oracle 查询 LOB 字段大小
  • 原文地址:https://www.cnblogs.com/Untergehen/p/14307292.html
Copyright © 2020-2023  润新知