HDU 6740 kmp最小循环节

题意:
给一个无线循环小数的前几位,给n,m

选择其中一种出现在前几位的循环节方式(a个数),循环节的长度b

使得n*a-m*b最大

样例:

2 1

12.1212

输出 6 

选择2,2*1-1*1=1;

选择12,2*4-2*1=6;

选择21,2*3-2*1=4;

选择212,2*3-3*1=3;

扫描二维码关注公众号,回复: 9446330 查看本文章

选择1212,2*4-4*1=4;

思路:

将小数部分,倒过来,求每个点的最小循环节,kmp中i-next[i]代表最小循环节

当倒过来的小数部分,n*i-m*(i-next[i])中的最大就是答案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define il inline
 5 #define it register int
 6 #define inf 0x3f3f3f3f
 7 #define lowbit(x) (x)&(-x)
 8 #define mem(a,b) memset(a,b,sizeof(a))
 9 #define mod 998244353
10 const int maxn=1e7+10;
11 ll n,m;
12 int nexts[maxn];
13 char s[maxn],s2[maxn];
14 int p2=0;
15 il void GetNext(int l){
16     int i=0;
17     int j=-1;
18     nexts[0]=-1;
19     while(i<l){
20         if(j==-1 || s2[i]==s2[j]){
21             i++;
22             j++;
23             nexts[i] = j;
24         }
25         else
26             j = nexts[j];
27     }
28     return;
29 }
30 int main(){
31     while(~scanf("%lld%lld",&n,&m)){
32         scanf("%s",s);
33         int l=strlen(s);p2=0;
34         int i;
35         for(i=0;i<l;i++){
36             if(s[i]=='.'){
37                 break;
38             }
39         }
40         for(int k=l-1;k>i;k--){
41             s2[p2++]=s[k];
42         }
43         GetNext(p2);
44         ll maxx=-1e18;
45         for(i=1;i<=p2;i++){
46             maxx=max(maxx,(ll)i*n-(ll)(i-nexts[i])*m);
47             //cout<<i<<" "<<(i-nexts[i])<<endl;
48         }
49         printf("%lld\n",maxx);
50     }
51     return 0;
52 }
View Code

kmp模板

 1 inline void getnext(char *ss){
 2     mem(ne,0);
 3     int l=strlen(ss);
 4     int i=0,j=-1;ne[0]=-1;
 5     while(i<l){
 6         if (j == -1 || ss[i] == ss[j])
 7         {
 8             i++;
 9             j++;
10             ne[i] = j;
11         }
12         else{
13             j = ne[j];
14         }
15     }
16     return;
17 }
18 inline int kmp(char *ss,char *s){
19     int l=strlen(s),ls=strlen(ss);
20     int i=0,j=0,ans=0;
21     while(i<l){
22         if(j==-1||s[i]==ss[j])
23         {
24             i++;
25             j++;
26         }
27         else
28             j=ne[j];
29         if(j==ls)
30         {
31             ans++;
32             j=ne[j];
33         }
34     }
35     return ans;
36 }
View Code

 待补全

猜你喜欢

转载自www.cnblogs.com/luoyugongxi/p/12369794.html