zoukankan      html  css  js  c++  java
  • hdu4669(递推,注意每个数位数不一定是1!!WA了许久)

    题意:

    一串项链,每颗珠子上有一个数字,任选连续的一段,按顺时针顺序将它们的数字拼起来,若新的数字是k的倍数,则这个数字是一个 wonderful value 。求有多少个 wonderful value 。

    题解:

    由于K非常小,我们可以用dp[j][i]表示以第j个数结尾的所有数字中模k为i的方案为多少,那么计算dp[j+1][i]的时候乘上偏移值并加上j+1个珠子的值就行了。复杂度为nk。

    注意如果读入数就去模的话,要记下原来的数的长度,比如9 和123拼起来9要乘1000,如果123先取模的话可能就乘100或者10了。就是这里卡了两个多少时……

    //#pragma comment(linker, "/STACK:102400000")
    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 50009
    using namespace std;
    int m,n,T,k;
    int a[N],ep,w[N],xp[10];
    int num[2][209];
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        int ncase=0;
        while(scanf("%d%d",&n,&k)==2)
        {
            xp[0]=1;
            for(int i=1; i<10; i++)
                xp[i]=(xp[i-1]*10)%k;
            int sw=0;
            char str[10];
            memset(num,0,sizeof(num));
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                sprintf(str,"%d",a[i]);
                w[i]=strlen(str);
                sw+=w[i];
            }
            ep=1;
            for(int i=0; i<sw; i++)
                ep=(ep*10)%k;
            int cur=0,last=1,tp=0;
            for(int i=1; i<=n; i++)
            {
                memset(num[cur],0,sizeof(num[cur]));
                for(int j=0; j<k; j++)if(num[last][j])
                        num[cur][(j*xp[w[i]]+a[i])%k]+=num[last][j];
                num[cur][a[i]%k]++;
                swap(cur,last);
                tp=(tp*xp[w[i]]+a[i])%k;
            }
            LL ans=0;
            for(int i=1; i<=n; i++)
            {
                memset(num[cur],0,sizeof(num[cur]));
                for(int j=0; j<k; j++)if(num[last][j])
                        num[cur][(j*xp[w[i]]+a[i])%k]+=num[last][j];
                num[cur][a[i]%k]++;
                tp=(tp*xp[w[i]]+a[i])%k;
                num[cur][tp]--;
                ans+=num[cur][0];
                swap(cur,last);
                tp=((tp-a[i]*ep)%k+k)%k;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    ARM标准汇编与GNU汇编
    使用友元,编译出错fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1786) 的解决
    C++中值传递,引用传递,指针传递
    C++命名空间的用法
    关于初始化C++类成员
    vivi的配置与编译
    C++ 容器
    vivi分区问题,及移植时需要修改的地方(转)
    基于S3C2410的VIVI移植
    拷贝构造函数什么时候调用?
  • 原文地址:https://www.cnblogs.com/sbaof/p/3341126.html
Copyright © 2011-2022 走看看