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 }
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 }
时间: 2024-09-17 12:12:03