HDU4162 Shape Number 最小表示法

题意:此题是将序列都减去前面的数如果小于0+8然后求按最小字典序不改变序列原序的情况下输出用最小表示法做

这里用到最小表示法:其维护ij指针,分别指向(共有L(串长)个串)其中2个串(其实只有一个串,拆成2个串好理解点)的串头(注意当比较这两个串的大小的时候ij都不动,任然指串头,而这个串头是指以该位置开始而得到的串的串头),他是通过k(因为如果不引入k,而ij是移动的,比较完成后ij回不了串头)来比较这两个串,即i+kj+k就是比较这两个串时的指针。。。。。。。 

然后,当不相等的时候,因为我们求的是最小的串,所以要移动大的指针,而小的指针不动,而这个小的指针很有可能就是我们所想要求的指针。。。。而移动的幅度是k+1使效率大大提高。。。。。因为如果移到[大指针后.....k]中的一个的话,

以这个位置为开头的串也一定比小串大。。。。。注意一点,ij指的位置都可能是想求的位置。。。。。。

总之,求最小表示,就小的不变,求最大表示就大不变。。。。。

还有一点,就是始终保持i<j,因为如果i == j的话事实上就在比较同一个串。。。。没意义,而最后返回的就是i == j

的指针,而这个指针极小可能是想要的结果。。。。。最后为什么返回小的那个呢?因为到达该位置就不在动了。。

而另外一个指针已经后移到出界了(即该指针 == L

#include<iostream>
#include <aLgorithm>
#include <cstdLib>
using namespace std;
int Len;
char a[300100];char b[300100];

 int MinimumRepresentation(char *s,int L)//串s[0~L-1]的最小表示位置
 {
     int i = 0, j = 1, k = 0,t;
     while (i +k< L && j+k < L && k < L)//找不到比它还小的 或者 完全匹配
     {
         t = s[(i+k)%L] - s[(j+k)%L];
         //if (s[(i+k) >= L ? i+k-L : i+k] == s[(j+k) >= L ? j+k-L : j+k])
         if (t == 0)
             k++;//相等的话,检测长度加1
         eLse
         {
             if (t > 0)//大于的话,s[i]为首的肯定不是最小表示,最大表示就改<
                 i += k + 1;
             eLse
                 j += k + 1;
             if (i == j)
                 j++;
             k = 0;
         }
     }
     return i;
 }
int main()
{    
    while(~scanf("%s",&a))
    {   
        int s1=0;
        int Lena=strLen(a);
        for(int i=0;i<Lena;i++)
        {
            if(a[(i+1)%Lena]>=a[i])
            b[i]=a[(i+1)%Lena]-a[i]+'0';
            eLse
            b[i]=8-(a[i]-a[(i+1)%Lena])+'0';            
        }
        int pos=0;
        pos=MinimumRepresentation(b,Lena);
        
        for(int z=0;z<Lena;z++)
        {
            printf("%c",b[(pos+z)%Lena]);
        }
        puts("");

    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值