zoukankan      html  css  js  c++  java
  • 初涉最小表示法&&bzoj1398: Vijos1382寻找主人 Necklace

    把最小表示法的坑填了

    Description

    给定两个项链的表示,判断他们是否可能是一条项链。

    Input

    输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的)。

    Output

    如果两条项链不可能同构,那么输出’No’,否则的话,第一行输出一个’Yes’
    第二行输出该项链的字典序最小的表示。 设L = 项链长度,L <= 1000000。

    Sample Input

    2234342423
    2423223434

    Sample Output

    Yes
    2234342423

    题目分析

    这里有最小表示法的论文https://wenku.baidu.com/view/c6c5e7335a8102d276a22fa6.html。

    关键在于if (s[(i+k)%n]!=s[(j+k)%n])时的快速重配。

    还有值得注意的是重配之后i有可能等于j,所以要i++,这个细节处理挺容易忘掉的。

    是种挺优美的思想。

     1 #include<bits/stdc++.h>
     2 const int maxn = 1000035;
     3 
     4 int n,sval,tval;
     5 char s[maxn],t[maxn];
     6 
     7 int calc(char *s)
     8 {
     9     int i = 0, j = 1, k = 0;
    10     while (i<n && j<n && k<n)
    11     {
    12         if (s[(i+k)%n]==s[(j+k)%n]) k++;
    13         else{
    14             if (s[(i+k)%n] > s[(j+k)%n])
    15                 i += k+1;
    16             else j += k+1;
    17             if (i==j) i++;
    18             k = 0;
    19         }
    20     }
    21     return std::min(i, j);
    22 }
    23 int main()
    24 {
    25     scanf("%s%s",s,t);
    26     n = strlen(s);
    27     sval = calc(s), tval = calc(t);
    28     bool fl = 1;
    29     for (int i=0; i<n; i++)
    30         if (s[(i+sval)%n]!=t[(i+tval)%n]){
    31             fl = 0;
    32             break;
    33         }
    34     if (!fl) puts("No");
    35     else{
    36         puts("Yes");
    37         for (int i=sval; i<sval+n; i++)
    38             putchar(s[i%n]);
    39         putchar('
    ');
    40     }
    41     return 0;
    42 }

    END

  • 相关阅读:
    LDD3 第7章 Time,Delays and Deferred Work
    4412 gpio读取pwm
    LDD快速参考
    4412 4路pwm输出
    PCB六层板学习(一)
    STM32 TIM3 PWM输出 4路
    4412 学习目录总结
    4412 Linux定时器
    4412 SPI驱动
    4412 i2c驱动
  • 原文地址:https://www.cnblogs.com/antiquality/p/9275322.html
Copyright © 2011-2022 走看看