39行代码AC_HDU-6740 2019CCPC秦皇岛 J MUV LUV EXTRA(KMP变形)

励志用少的代码做高效表达


Problem description

One day, Kagami Sumika is stuck in a math problem aiming at calculating the length of a line segment with given statements and constraints. Since Sumika has no idea about it, she takes out a ruler and starts to measure the length. Unfortunately, the answer is an infinite decimal and she only got the first some digits of the answer from the ruler.
Sumika guesses that the answer is a rational number, which means that there exists two integers p, q that the answer equals qp. In this situation, the answer can be expressed as an infinte repeated decimal. For example, 12 = 0.500 … , 13 = 0.333 … , 910= 0.8999 … ,3635= 1.0285714285714 … .Sumika wants to guess the original number from the digits she got. Note that a number may has more than one way to be expressed such as 1.000 … = 0.999 … . Sumika won’t transform the digits she got to another form when guessing the original number.
Furthermore, Sumika relizes that for a repeating part, either too long or the appeared length too short will make the result unreliable. For example, if the decimal she measured is 1.0285714285714, it is obviously unreliable that the repeating part is “0285714285714”, since it is too long, or “428571”, since the appeared length is too short, which equals 7, the length of “4285714”. In this case, the best guess is “285714”, whose length is 6 and the appeared length is 12. So formally, she defines the reliability value of a repeating part, whose length is l and the appeared length is p, as the following formula:
a ∗ p − b ∗ l a * p - b * l apbl
Where a and b are given parameters.
Last but not least, you can ignore the integer parts of the decimal. It is just for restoring the scene. And the repeating part you guess should be completely repeated at least once and is still repeating at the end currently.
Please help Sumika determine the maximum reliability value among all repeating parts.

Input

The first line contains two positive integers a, b (1 ≤ a, b ≤ 109), denoting the parameters.
The next line contains a string s (1 ≤ |s| ≤ 107) in decimal form, denoting the first some digits of the accurate result.
It is guaranteed that there is exactly one decimal point in s and s is a legal non-negative decimal without leading “-”(the minus sign).

Output

Output a single line containing an integer, denoting the maximum reliability value.


解题思路

如果有对KMP还不懂的同学——>KMP算法_图示分析+解析+例题

这个题很巧妙的利用了 KMP

我们需要反过来求kmp得next数组,枚举前缀,那么i就是循环节出现的总长度,而i-next[i]就是循环节长度。


代码展示
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const ll INF=1e18;
ll a,b,res;
int i,j,k;
char s[10000010], s1[10000010];
int Next[10000010];
 
void getnext(char s[],int Next[]) {
    int q,k;
    int len=strlen(s);
    Next[0] = 0;
    for (q = 1,k = 0; q < len; ++q) {
        while(k>0 && s[q]!=s[k]) k = Next[k-1];
        
        if (s[q] == s[k]) k++;
        Next[q] = k;
    }
}
 
int main() {
    while(cin>>a>>b) {
        memset(Next,0,sizeof Next);
        cin>>s1;
        int len1=strlen(s1);
        int len=0;
        for(i=len1-1; i>=0; i--) {
            if(s1[i]=='.') break;
            s[len1-i-1]=s1[i];
            len++;
        }
        getnext(s,Next);
        ll ans=-INF;
        for(i=0; i<len; i++) {
            res=a*(i+1)-b*(i+1-Next[i]);	//核心代码
            if(res>ans) ans=res;
        }
        cout << ans << '\n';
    }
return 0; }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来老铁干了这碗代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值