hdu4933 Miaomiao's Function 数位dp+大数模板

Miaomiao's Function

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 228    Accepted Submission(s): 59


Problem Description
Firstly , Miaomiao define two functions f(x) , g(x):


(K is the smallest integer which satisfied x + 9 * K > 0)

if   e.g. g(178) = 1 - 7 + 8 = 2 , g(1) = 1 , g(1234) = 1 - 2 + 3 - 4 = -2;

For example f(20140810) = f(2 + 0 + 1 + 4 + 0 + 8 + 1 + 0) = f(16) = f(1 + 6) = f(7) = 7

Then , you are given two integers L , R( L <= R) . 
Answer is defined as  .
Please caculate (Answer Mod f(Answer) + f(Answer)) Mod f(Answer).
Pay attantion ! If f(Answer) = 0 , please output "Error!"
 

Input
There are many test cases. In the first line there is a number T ( T <= 50 ) shows the number of test cases.
For each test cases there are two numbers L ,R ( 0 <= L,R <= 10^100 ).

For your Information , L , R don't have leading zeros.
 

Output
For each opeartion , output the result.
 

Sample Input
  
  
2 0 0 0 21
 

Sample Output
  
  
Error! 1
Hint
The Answer is 0 and 13. So the result is Error! and 13 Mod (1 + 3) = 1
 
根据题目中的f(x)的定义,求出answer后若answer>0,f(x)=answer%9,如果answer%9==0,f(x)=9;需要判断answer是否为0,就需要用大数来求了。
dp[pos][f][one],pos表示位置,f表示是否受限,one表示是否是第一位。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<ostream>
#include<istream>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#define fi first
#define se second
#define pii pair<int,int>
#define inf (1<<30)
#define eps 1e-8
#define ll long long
using namespace std;
const int maxn=510005;
const ll mod=1000000007;
struct bigint //flag表示正负,a数组从低位到高位
{
    int flag;
    int a[210];
    bigint() { flag=1; memset(a,0,sizeof a); }
};
bigint operator +(bigint a, bigint b);
bigint operator -(bigint a, bigint b);
bigint operator +(bigint a, bigint b)
{
    if (a.flag==b.flag)
    {
        bigint c;
        int g=0;
        for(int i=1;i<=200;i++)
        {
            c.a[i]=a.a[i]+b.a[i]+g;
            g=c.a[i]/10;
            c.a[i]%=10;
        }
        c.flag=a.flag;
        return c;
    }
    else
    {
        if (a.flag==1)
        {
            b.flag=1; return a-b;
        }
        else
        {
            a.flag=1; return b-a;
        }
    }
}
int cmp(const bigint &a, const bigint &b)
{
    for(int i=200;i>=1;i--) if (a.a[i]!=b.a[i]) if (a.a[i]<b.a[i]) return -1; else return 1;
    return 0;
}
bigint operator -(bigint a, bigint b)
{
    if (a.flag==-1 || b.flag==-1)
    {
        if (a.flag==-1 && b.flag==-1)
        {
            a.flag=1; b.flag=1;
            return b-a;
        }
        if (a.flag==-1)
        {
            a.flag=1; a=a+b;
            a.flag=-1; return a;
        }
        if (b.flag==-1)
        {
            b.flag=1; return a+b;
        }
    }
    if (cmp(a,b)==-1)
    {
        a=b-a; a.flag=-1;
        return a;
    }
    bigint c; int g=0;
    for(int i=1;i<=200;i++)
    {
        c.a[i]=a.a[i]-b.a[i]-g;
        if (c.a[i]<0) c.a[i]+=10, g=1; else g=0;
    }
    return c;
}
bigint operator *(bigint a, int t)
{
    if (t==0) { bigint c; return c; }
    if (t<0)
    {
        a.flag*=-1; t*=-1;
    }
    int g=0; bigint c; c.flag=a.flag;
    for(int i=1;i<=200;i++)
    {
        c.a[i]=a.a[i]*t+g;
        g=c.a[i]/10;
        c.a[i]%=10;
    }
    return c;
}
int iszero(bigint z)
{
    for(int i=1;i<=200;i++) if (z.a[i]!=0) return 0;
    return 1;
}
bigint toBigint(char *s)
{
    int len=strlen(s+1);
    bigint c;
    for(int i=len;i>=1;i--) c.a[len-i+1]=s[i]-'0';
    return c;
}
bigint toBigint(int a)
{
    bool flag=true;
    if(a<0) {
        a=-a;
        flag=false;
    }
    char s[10];
    int cnt=1;
    while(a) {
        s[cnt++]=(a%10+'0');
        a/=10;
    }
    for(int i=1,j=cnt-1;i<j;i++,j--)
        swap(s[i],s[j]);
    s[cnt]='\0';
    bigint q=toBigint(s);
    if(!flag)
        q.flag=-1;
    return q;
}
int modd(bigint c, int z)
{
    int g=0;
    for(int i=200;i>=1;i--) g=(g*10+c.a[i])%z;
    if (c.flag==-1) g*=-1;
    return g;
}
char l[1005];
char r[1005];
bigint pw[105];
bigint g[105];
bigint dp[105][2];
bool vis[105][2];
bigint dfs(int e,int flag,char* s,int one)
{
    if(e==0) {
        if(flag==1)
            return toBigint(45);
        else
            return toBigint((s[0]-'0')*(s[0]-'0'+1)/2);
    }
    if(flag && vis[e][one])
        return dp[e][one];
    bigint ans;
    int mx=(flag?9:s[e]-'0');
    for(int i=0;i<=mx;i++) {
        int f;
        if(flag || (i<mx)) f=1;
        else f=0;
        if(f) ans=ans+pw[e-1]*i;
        else ans=ans+g[e-1]*i;
        if(i==0 && one)
            ans=ans+dfs(e-1,f,s,1);
        else
            ans=ans-dfs(e-1,f,s,0);
    }
    if(flag) {
        vis[e][one]=1;
        dp[e][one]=ans;
    }
    return ans;
}
bigint cal(char* s)
{
    int len=strlen(s);
    for(int i=0,j=len-1;i<j;i++,j--)
        swap(s[i],s[j]);
    bigint tmp;
    memset(g[0].a,0,sizeof(g[0].a));
    tmp.a[1]=1;
    g[0].a[1]=(s[0]-'0');
    g[0]=g[0]+tmp;
    for(int i=1;i<len;i++) {
        g[i]=g[i-1]+pw[i-1]*(s[i]-'0');
    }
    return dfs(len-1,0,s,1);
}
void solve()
{
    bigint R=cal(r);
    bigint L=cal(l);
    int u=0;
    for(int i=strlen(l)-1,j=1;i>=0;i--,j++) {
        if(j&1)
            u+=l[i]-'0';
        else
            u-=l[i]-'0';
    }
    bigint tmp=toBigint(u);
    bigint ans=R-L+tmp;
    if(iszero(ans)) {
        printf("Error!\n");
        return;
    }
    int m=modd(ans,9);
    if(m<0) m+=9;
    if(m==0) m=9;
    int o=modd(ans,m);
    if(o<0)
        o+=m;
    printf("%d\n",o);
    return;
}
int main()
{
    pw[0].a[2]=1;
    for(int i=1;i<=100;i++) {
        pw[i]=pw[i-1]*10;
    }
    int t;
    scanf("%d",&t);
    memset(vis,0,sizeof(vis));
    while(t--) {
        scanf("%s%s",l,r);
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值