spoj1433 KPSUM

题意:略;

首先知道10,20,......100,200,1000的前面的符号都是负号。

举具体例子:221时,计算过程为

000-009,     010-019,   020-029......,090-099;    100-199;   200-209, 210-219,   220-221;

首先第1位能取0,1,2(2是上界)。先看选1时,这时没有前倒0,没到上界。因此能直接计算,一共100项,百位和为0,再算出后缀。然后第1位取0

第1位取0:第二位取1-9,能直接计算。观察到只要没有前倒0或者没到上限就能直接算从结果。类似第一位取2,第二位取0-1,时因为没到上限,直接算。

如果一直到了最后一位都有前倒0或上限,即000-009,220-221。就暴力计算,一直有上限的情况要传递前缀。

因此dfs的参数有5个,当前位,有无前倒0,是否取上限,前缀位数,前缀。

代码v1.1

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#include <unordered_set>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=210,SSZ=10*SZ,APB=20,INF=0x7FFFFFFF,mod=1000000007;
lon n,arr[SZ],sz;

void release()
{
    
}

lon func(lon x)
{
    lon res=0,t=1;
    for(;x;x/=10)res+=x%10*t,t=-t;
    res*=-t;
    return res;//+开头 
}

lon dfs(lon pos,lon lim,lon lead,lon pre,lon fix)
{
    lon up=lim?arr[pos]:9,res=0;
    if(!lead&&!lim)
    {
        lon tot=(pre+(sz-pos))&1;
        if(!tot)
        {
            if(!(pre&1))res=0;
            else res=45*((lon)pow(10,sz-pos-1));
        }
        else
        {
            res=(lon)pow(10,sz-pos)/2;
        }
        return res;
    }
    else if(pos==sz-1)
    {
        if(lead)for(lon i=1;i<=up;++i)res+=(i&1?1:-1)*i;
        else if(lim)
        {
            for(lon i=0;i<=up;++i)
            {
                if(pre&1)res+=func(fix*10+i);
                else res+=(i&1?1:-1)*func(fix*10+i);
            }
            if(pre&1)res=-res;
        }
        return res;
    }
    else
    {
        for(lon i=0;i<=up;++i)
        {
            lon nlim=lim&&i==up,nlead=lead&&i==0;
            lon cur=0;
            if(!nlim&&lim||(!nlead&&lead&&pos))
            {
                lon tot=pre+(sz-pos);
                if(!(tot&1))
                {
                    cur-=func(fix*10+i)*pow(10,sz-pos-1);
                }
            }
            cur+=dfs(pos+1,nlim,nlead,nlead?pre:pre+1,fix*10+i);
            res+=cur;
        }
        return res;
    }
}

lon calc(lon x)
{
    sz=0;
    for(;x;x/=10)arr[sz++]=x%10;
    reverse(arr,arr+sz);
    return dfs(0,1,1,0,0);
}

void init()
{
    cout<<calc(n)<<endl;
}

void work()
{
    
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\2.txt","r",stdin);
    //freopen("d:\\3.txt","w",stdout);
    lon casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(lon time=1;time<=casenum;++time)
    for(lon time=1;cin>>n,n;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

v1.0

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#include <unordered_set>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=210,SSZ=10*SZ,APB=20,INF=0x7FFFFFFF,mod=1000000007;
lon n,arr[SZ],sz;

void release()
{
    
}

lon func(lon x)
{
    lon res=0,t=1;
    for(;x;x/=10)res+=x%10*t,t=-t;
    res*=-t;
    return res;//+开头 
}

lon dfs(lon pos,lon lim,lon lead,lon pre,lon fix)
{
    //cout<<pos<<endl;
    lon up=lim?arr[pos]:9,res=0;
    if(pos==sz)return 0;
    else if(pos==sz-1)
    {
        if(!fix)for(lon i=1;i<=up;++i)res+=(i&1?1:-1)*i;
        else if(lim)
        {
            for(lon i=0;i<=up;++i)
            {
                if(pre&1)res+=func(fix*10+i);
                else res+=(i&1?1:-1)*func(fix*10+i);
                //cout<<fix*10+i<<endl;
            }
            if(pre&1)res=-res;
            //cout<<res<<endl;
        }
        else
        {
            if(!(pre&1))
            {
                for(lon i=0;i<=up;++i)res+=(i&1?1:-1)*i;
                //cout<<res<<endl;
            }
            else for(lon i=1;i<=up;++i)res+=i;
        }
        return res;
    }
    else if(!lead&&!lim)
    {
        lon tot=(pre+(sz-pos))&1;
        if(!tot)
        {
            if(!(pre&1))res=0;
            else res=45*((lon)pow(10,sz-pos-1));
        }
        else
        {
            res=(lon)pow(10,sz-pos)/2;
        }
        return res;
    }
    else
    {
        for(lon i=0;i<=up;++i)
        {
            lon nlim=lim&&i==up,nlead=lead&&i==0;
            lon cur=0;
            if(!nlim&&lim||(!nlead&&lead&&pos))
            {
                //if(pre&1);
                //else
                {
                    lon tot=pre+(sz-pos);
                    if(tot&1)
                    {
                        
                    }
                    else
                    {
                        cur-=func(fix*10+i)*pow(10,sz-pos-1);
                    }
                    
                }
            }
            //cout<<"i: "<<pos<<" "<<i<<" "<<cur<<endl;
            cur+=dfs(pos+1,nlim,nlead,nlead?pre:pre+1,fix*10+i);
            res+=cur;
            //cout<<"i: "<<pos<<" "<<i<<" "<<cur<<" "<<(!nlead&&lead)<<endl;
        }
        return res;
    }
}

lon calc(lon x)
{
    sz=0;
    for(;x;x/=10)arr[sz++]=x%10;
    reverse(arr,arr+sz);
    return dfs(0,1,1,0,0);
}

void init()
{
    cout<<calc(n)<<endl;
}

void work()
{
    
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\2.txt","r",stdin);
    //freopen("d:\\3.txt","w",stdout);
    lon casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(lon time=1;time<=casenum;++time)
    for(lon time=1;cin>>n,n;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

 

posted @ 2019-04-14 11:35  degvx  阅读(150)  评论(0编辑  收藏  举报