Codeforces Round #451 (Div. 2)F. Restoring the Expression 字符串hash

题目链接:F. Restoring the Expression

题意:输入一个字符串,然后让你输出一个加法等式

题解:枚举最后一部分的长度i,前面某一部分的长度只能为i--1或者i.然后用字符串hash先判断是否相等,相等的话在模拟判断一下数值是否相等。
hash[]值用前缀,用b[]保存,对于某一段[l,r]的字符的hash值=(b[r]-(b[l-1]*p[r-l+1])%mod)%mod;p数值的保存的是base的多少次幂取mod.

#include<bits/stdc++.h>
#include<set>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
typedef unsigned long long ull;
const ull b1=9973;
const ull b2=100000007;
const int base=10;
const int mod=1e9+7;
const int maxn=1e6+5;
using namespace std;
int n;
ll s[maxn],p[maxn],b[maxn];
char a[maxn];
ll get_val(int l,int r)
{
    ll ans=0;
    if(r-l+1<=0||l-1<0||r<0)return 0;
    ans=(b[r]-(b[l-1]*p[r-l+1])%mod)%mod;
    ans=(ans+mod)%mod;
    return ans;
}
bool ok(int la,int lb,int lc)
{
    int po1=la,po2=la+lb,po3=la+lb+lc;
    int tmp=0,up=0;
    while(lc--)
    {
       // tmp=po1>0?s[po1--]:0+po2>la?s[po2--]:0+up;
        int t1=po1>0?s[po1--]:0;
        int t2=po2>la?s[po2--]:0;
        tmp=t1+t2+up;
       // cout<<t1<<' '<<t2<<endl;
        //cout<<po1>0?s[po1--]:0<<' '<<po2>la?s[po2--]:0<<endl;
        up=tmp/10;tmp%=10;
      //  cout<<tmp<<' '<<up<<' '<<s[po3]<<endl;
        if(tmp!=s[po3--])return false;
    }
    if(up)return false;
    for(int i=1;i<=n;i++)
    {
        if(i==la+1)
        {
            printf("+");
        }
        else if(i==la+lb+1)
        {
            printf("=");
        }
        printf("%lld",s[i]);
    }
    printf("\n");
    return true;
}
bool slove(int la,int lb,int lc)
{
    if(la<1||la>lc||lb>lc||lb<1)return false;
    if((lb>1&&s[la+1]==0)||(lc>1&&s[la+lb+1]==0))return false;
    ll va=get_val(1,la);
    ll vb=get_val(la+1,la+lb);
    ll vc=get_val(la+lb+1,la+lb+lc);
    if((va+vb)%mod==vc&&ok(la,lb,lc))return true;
    else return false;
}
int main()
{
  //  std::ios::sync_with_stdio(false);
  //  cin.tie(0);
   // cout.tie(0);
    scanf("%s",a+1);
    n=strlen(a+1);
    for(int i=1;i<=n;i++)
    {
        s[i]=a[i]-'0';
    }
    p[0]=1;b[0]=0;
    for(int i=1;i<=n;i++)
    {
        b[i]=(b[i-1]*base+s[i])%mod;
        p[i]=(p[i-1]*base)%mod;
    }
    for(int i=1;i<=n;i++)
    {
        if(slove(i-1,n-i-(i-1),i)||slove(i,n-i-i,i)||slove(n-i-i,i,i)||slove(n-i-(i-1),i-1,i))
        {
            break;
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/lhclqslove/p/8312976.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值