zoukankan      html  css  js  c++  java
  • 最强阵容加强版

    1613: 最强阵容加强版

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    拿着新换来的英雄卡,小李满心欢喜的准备和同学们PK一下。
    他们的游戏规则非常简单,双方把自己的牌绕成一圈,然后指定一个起点,从该张牌开始顺时针方向往后取,谁取出的字符串字典序更小(从左到右开始比较,碰到第一个不一样的字符进行比较,比较规则为a<b<…<z)谁将获得胜利。具体规则可参考样例。虽然现在小李的牌已经很好了,但是你能不能帮他快速算出起始位置,使得他能够派出最强阵容。

    输入

    第一行n,表示共有n张牌。
    第二行共n个用一个空格隔开的小写字母,表示给定的一圈牌起始序列。

    输出

    仅一个整数,能获得最小字典序字符串的起点位置。如果有多个位置开始的字符串一样,则输出最小的那个位置,且第一个位置从1开始。

    样例输入

    4 b c a b

    样例输出

    3

    提示

    【样例说明】 

    四个位置取出的字符串分别为bcab,cabb,abbc,bbca,显然最小位置是3。

    【数据规模】 

    30%的数据,1<=n<=10

    60%的数据,1<=n<=1000

    100%的数据,1<=n<=300000

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 int a[600005];
     6 int main()
     7 {
     8     int n; scanf("%d",&n); 
     9     int ch; scanf("%c",&ch);
    10     for (int i=1;i<n;i++) scanf("%c ",&a[i]),a[i+n]=a[i];
    11     scanf("%c",&a[n]); a[n+n]=a[n];
    12     int i=1,j=2;
    13     while (j<=n){
    14         int k;
    15         for (k=0;k<n;k++)
    16             if (a[i+k]<a[j+k]){
    17                 j=j+k+1; break;
    18             } else if (a[i+k]>a[j+k]){
    19                 i=j; j=j+1; break;
    20             }
    21         if (k==n) j=j+k;
    22     }
    23     printf("%d",i);
    24 }
    View Code
     1 #include<iostream>  
     2 #include<cstdio>  
     3 #include<cmath>  
     4 #include<cstring>  
     5 #include<algorithm>  
     6 using namespace std;  
     7 #define P 27  
     8 #define P1 1795876273  
     9 #define P2 2001122927  
    10 #define N 600005  
    11 long long a[N],f1[N],f2[N],fp1[N],fp2[N];  
    12 #define F1(i,j) mo(f1[j]-f1[i-1]*fp1[j-i+1],P1)  
    13 #define F2(i,j) mo(f2[j]-f2[i-1]*fp2[j-i+1],P2)  
    14 int mo(long long a,int q)
    15 {
    16     a=a%q; if (a<0) a+=q;
    17     return a;
    18 }
    19 int check(int i,int j,int k){  
    20     if (k==1) {  
    21         if (a[i]<=a[j]) return 0;  
    22         return 1;  
    23     }  
    24     //cout<<i<<" "<<j<<" "<<i+k/2-1<<" "<<j+k/2-1<<endl;
    25     if (F1(i,i+k/2-1)==F1(j,j+k/2-1) && F2(i,i+k/2-1)==F2(j,j+k/2-1))  
    26         check(i+k/2,j+k/2,(k+1)/2);
    27     else check(i,j,k/2);
    28 }  
    29 int main()  
    30 {  
    31     int n; scanf("%d",&n);   
    32     int ch; scanf("%c",&ch);  
    33     for (int i=1;i<n;i++) scanf("%c ",&a[i]),a[i+n]=a[i];  
    34     scanf("%c",&a[n]); a[n+n]=a[n];  
    35     for (int i=1;i<=n+n;i++) a[i]-=96;  
    36     for (int i=1;i<=n+n;i++) f1[i]=mo(f1[i-1]*P+a[i],P1);  
    37     for (int i=1;i<=n+n;i++) f2[i]=mo(f2[i-1]*P+a[i],P2);  
    38     fp1[0]=1; fp2[0]=1;
    39     for (int i=1;i<=n+n;i++) fp1[i]=mo(fp1[i-1]*P,P1);
    40     for (int i=1;i<=n+n;i++) fp2[i]=mo(fp2[i-1]*P,P2);
    41     //cout<<check(1,2,n)<<" "<<check(2,3,n)<<" "<<check(3,4,n);
    42     int ans=1;  
    43     for (int i=2;i<=n;i++)  
    44         if (check(ans,i,n)) ans=i;  
    45     printf("%d",ans);  
    46 }  
    View Code
  • 相关阅读:
    2016"百度之星"
    ZOJ 3703 Happy Programming Contest(01背包的灵活运用)
    LA 3942 Remember the Word (Trie树)
    ZOJ 3700 Ever Dream(Vector)
    Hdoj 1686 Oulipo
    2017总结,2018计划
    Ubuntu16.04 + caffe-ssd + [CPU_ONLY] + KITTI 训练总结
    【转载】The Elements of Programming Style之代码风格金科玉律
    qt中setStyleSheet导致的内存泄漏
    【转】用枚举定义有意义的数组下标
  • 原文地址:https://www.cnblogs.com/SXia/p/7612103.html
Copyright © 2011-2022 走看看