fzuoj Problem 2179 chriswho

http://acm.fzu.edu.cn/problem.php?pid=2179

Problem 2179 chriswho

Accept: 57    Submit: 136 Time Limit: 10000 mSec    Memory Limit : 327680 KB

 Problem Description

Chriswho很喜欢数字,特别喜欢一种数字,它能整除它的每一位数字(如果该位是0当做能整除),比如说126这个数字他就很喜欢,因为126%1=126%2=126%6=0。为了让更多的人喜欢这样的数,他决定出一道这样的题目。求解1到n(包括1和n)之间有多少个这样的数字。

 Input

第一行是一个整数t表示case数(不超过10组)。接下来t行,每行一个整数n(1<=n<=9*10^18)。

 Output

输出t行,每行包括一个数字,表示满足条件的数字个数。

 Sample Input

2 9 15

 Sample Output

9 13

 Source

FOJ有奖月赛-2014年11月

分析:

因为1-9的lcm是2520,所以对于每一个数模2520,余数如果是自己的lcm的倍数那么就是。

所以dp[i][j][k]代表位数为i,模2520为j,lcm为k的数个数。

枚举后面加的数字g,用dp[i][j][k]去更新dp[i+1][(j*10+g)%2520][lcm(g,k)]。

还要注意一点lcm的个数只有48个,所以就可以开一个数组映射。

写了2种写法,递推写法因为有大量状态浪费速度相当慢。

DFS则快很多

AC代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<ctype.h>
  4 #include<algorithm>
  5 #include<iostream>
  6 #include<cstring>
  7 #include<vector>
  8 #include<cstdlib>
  9 #include<stack>
 10 #include<cmath>
 11 #include<queue>
 12 #include<set>
 13 #include<map>
 14 #include<ctime>
 15 #include<string.h>
 16 #include<string>
 17 #include<sstream>
 18 #include<bitset>
 19 using namespace std;
 20 #define ll long long
 21 #define ull unsigned long long
 22 #define eps 1e-11
 23 #define NMAX 1000000005
 24 #define MOD 1000000007
 25 #define lson l,mid,rt<<1
 26 #define rson mid+1,r,rt<<1|1
 27 #define PI acos(-1)
 28 template<class T>
 29 inline void scan_d(T &ret)
 30 {
 31     char c;
 32     int flag = 0;
 33     ret=0;
 34     while(((c=getchar())<‘0‘||c>‘9‘)&&c!=‘-‘);
 35     if(c == ‘-‘)
 36     {
 37         flag = 1;
 38         c = getchar();
 39     }
 40     while(c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘),c=getchar();
 41     if(flag) ret = -ret;
 42 }
 43 ll dp[19][2525][50];
 44 int lcm[11][2525],biao[50],m[2525];
 45 map<int,int>mp;
 46 int gcd(int a,int b)
 47 {
 48     return (b == 0)?a:gcd(b,a%b);
 49 }
 50
 51 void init()
 52 {
 53     for(int i = 0; i <= 9; i++)
 54         for(int j = 1; j <= 2520; j++)
 55             lcm[i][j] = i?i*j/gcd(i,j):j;
 56     int nct = 1;
 57     for(int i = 1; i <= 2520; i++) if(2520%i == 0)
 58     {
 59         m[i] = nct;
 60         biao[nct++] = i;
 61     }
 62     biao[0] = 1;
 63 //    cout<<biao[48]<<endl;
 64 }
 65
 66 char ch[25];
 67 int main()
 68 {
 69 #ifdef GLQ
 70     freopen("input.txt","r",stdin);
 71 //    freopen("o4.txt","w",stdout);
 72 #endif // GLQ
 73     init();
 74     int cas;
 75     scanf("%d",&cas);
 76     while(cas--)
 77     {
 78         scanf("%s",ch);
 79         int len = strlen(ch);
 80         memset(dp,0,sizeof(dp));
 81         for(int i = 0; i < ch[0]-‘0‘; i++)
 82             dp[0][i][biao[i]] = 1;
 83         int ha[2];
 84         ha[0] = ha[1] = ch[0]-‘0‘;
 85         for(int i = 1; i < len; i++)
 86         {
 87             int p = (i==len-1)?ch[i]-‘0‘+1:ch[i]-‘0‘;
 88             for(int j = 0; j < p; j++)
 89                 dp[i][(ha[0]*10+j)%2520][m[lcm[j][ha[1]]]] = 1;
 90             ha[0] = (ha[0]*10+p)%2520;
 91             ha[1] = lcm[p][ha[1]];
 92             int num = ch[i]-‘0‘;
 93             for(int j = 0; j < 2520; j++)
 94                 for(int k = 1; k <= 48; k++) if(dp[i-1][j][k])
 95                 {
 96                     ll d = dp[i-1][j][k];
 97                     for(int l = 0; l <= 9; l++)
 98                     {
 99                         int lc = m[lcm[l][biao[k]]];
100 //                        cout<<l<<" "<<lc<<" "<<lcm[l][biao[k]]<<endl;
101                         dp[i][(j*10+l)%2520][lc] += d;
102                     }
103                 }
104         }
105         ll ans = 0;
106         for(int i = 0; i < 2520; i++)
107             for(int j = 1; j <= 48; j++)
108             {
109                 if(i%biao[j] == 0) ans += dp[len-1][i][j];
110             }
111         if(len == 1) ans++;
112         ans--;
113         printf("%I64d\n",ans);
114     }
115     return 0;
116 }

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<ctype.h>
  4 #include<algorithm>
  5 #include<iostream>
  6 #include<cstring>
  7 #include<vector>
  8 #include<cstdlib>
  9 #include<stack>
 10 #include<cmath>
 11 #include<queue>
 12 #include<set>
 13 #include<map>
 14 #include<ctime>
 15 #include<string.h>
 16 #include<string>
 17 #include<sstream>
 18 #include<bitset>
 19 using namespace std;
 20 #define ll long long
 21 #define ull unsigned long long
 22 #define eps 1e-11
 23 #define NMAX 1000005
 24 #define MOD 1000000007
 25 #define lson l,mid,rt<<1
 26 #define rson mid+1,r,rt<<1|1
 27 #define PI acos(-1)
 28 template<class T>
 29 inline void scan_d(T &ret)
 30 {
 31     char c;
 32     int flag = 0;
 33     ret=0;
 34     while(((c=getchar())<‘0‘||c>‘9‘)&&c!=‘-‘);
 35     if(c == ‘-‘)
 36     {
 37         flag = 1;
 38         c = getchar();
 39     }
 40     while(c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘),c=getchar();
 41     if(flag) ret = -ret;
 42 }
 43 ll dp[20][2525][50];
 44 int mp[2520],ha[50],lcm[11][2520],shu[20];
 45
 46 int gcd(int x, int y)
 47 {
 48     return y?gcd(y,x%y):x;
 49 }
 50
 51 void init()
 52 {
 53     memset(dp,-1,sizeof(dp));
 54     int nct = 1;
 55     for(int i = 1; i <= 2520; i++) if(2520%i == 0)
 56     {
 57         ha[nct] = i;
 58         mp[i] = nct++;
 59     }
 60     for(int i = 0;i <= 9; i++)
 61         for(int j = 1; j <= 2520; j++)
 62             lcm[i][j] = (i==0)?j:i*j/gcd(i,j);
 63 }
 64
 65 ll dfs(int yu, int lc, int len,int limit)
 66 {
 67     if(len == 0)
 68         return yu%ha[lc] == 0;
 69     if(~dp[len][yu][lc] && !limit) return dp[len][yu][lc];
 70     ll ans = 0;
 71     int p = limit?shu[len]:9;
 72     for(int i = p; i >= 0; i--)
 73     {
 74         ans += dfs((yu*10+i)%2520, mp[lcm[i][ha[lc]]],len-1, limit && i == shu[len]);
 75     }
 76     if(!limit) dp[len][yu][lc] = ans;
 77     return ans;
 78 }
 79
 80 int main()
 81 {
 82 #ifdef GLQ
 83     freopen("input.txt","r",stdin);
 84 //    freopen("o4.txt","w",stdout);
 85 #endif // GLQ
 86     int cas;
 87     ll n;
 88     init();
 89     scanf("%d",&cas);
 90     while(cas--)
 91     {
 92         scanf("%I64d",&n);
 93         int nct=1;
 94         while(n)
 95         {
 96             shu[nct++] = n%10LL;
 97             n /= 10LL;
 98         }
 99 //        cout<<nct<<endl;
100         printf("%I64d\n",dfs(0,1,nct-1,1)-1);
101     }
102     return 0;
103 }

时间: 2024-10-17 20:22:51

fzuoj Problem 2179 chriswho的相关文章

fzuoj Problem 2236 第十四个目标(树状数组+dp)

Problem 2236 第十四个目标  Problem Description 目暮警官.妃英里.阿笠博士等人接连遭到不明身份之人的暗算,柯南追踪伤害阿笠博士的凶手,根据几起案件现场留下的线索发现凶手按照扑克牌的顺序行凶.在经过一系列的推理后,柯南发现受害者的名字均包含扑克牌的数值,且扑克牌的大小是严格递增的,此外遇害者与毛利小五郎有关. 为了避免下一个遇害者的出现,柯南将可能遭到暗算的人中的数字按关联程度排列了出来,即顺序不可改变.柯南需要知道共有多少种可能结果,满足受害人名字出现的数字严格

FZUOJ Problem 2178 礼物分配

Problem 2178 礼物分配 题目链接: Click Here~ Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N).对于每个礼物他们俩有着各自心中的价值vi和wi,他们要求各自分到的礼物数目|numv-numw|<=1,并且各自所衡量的礼物价值的差值|sumv-sumw|尽可能小,现在他们想知道最小的差值是多少.  Input 第一行为一个整数表示数据组数T. 接下来T组数组,每组

fzuoj Problem 2177 ytaaa

http://acm.fzu.edu.cn/problem.php?pid=2177 Problem 2177 ytaaa Accept: 113    Submit: 265Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description Ytaaa作为一名特工执行了无数困难的任务,这一次ytaaa收到命令,需要炸毁敌人的一个工厂,为此ytaaa需要制造一批炸弹以供使用. Ytaaa使用的这种新型炸弹由若干个炸药组成,每

fzuoj Problem 2129 子序列个数

http://acm.fzu.edu.cn/problem.php?pid=2129 Problem 2129 子序列个数 Accept: 162    Submit: 491Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description 子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a[p2]......a[pm]为a的一个子序列,其中1<=p1<p2<..

FZUOJ Problem 2200 cleaning DP

Problem 2200 cleaning  Problem Description N个人围成一圈在讨论大扫除的事情,需要选出K个人.但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法.  Input 第一行包含一个数T(T<=100),表示测试数据的个数. 接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N).  Output 输出满足题意的方案数,方案数很大,所以请输出方案数mo

FZUOJ Problem 2178 礼品配送

Problem 2178 礼物分配 题目链接: Click Here~ Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N).对于每一个礼物他们俩有着各自心中的价值vi和wi,他们要求各自分到的礼物数目|numv-numw|<=1,而且各自所衡量的礼物价值的差值|sumv-sumw|尽可能小,如今他们想知道最小的差值是多少.  Input 第一行为一个整数表示数据组数T. 接下来T组数组,每

【BZOJ】【2179】FFT快速傅里叶

FFT 做的第二道用到FFT的……好吧其实还是模板题-_-b 百度上说好像分治也能做……不过像FFT这种敲模板的还是省事=.= 1 /************************************************************** 2 Problem: 2179 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1236 ms 7 Memory:9184 kb 8 *********************

Problem 2238 Daxia &amp; Wzc&#39;s problem 1627 瞬间移动

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1627 http://acm.fzu.edu.cn/problem.php?pid=2238 对应的51NOD这个题,先把n--和没m-- 再套公式 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorit

FOJ月赛 2014年11月 题解

Problem A: Yellowstar的第一道题 写个暴力程序会发现若n*r*c 是偶数,则是必败态,输出0.000000 否则对于3*3*3 赢的位置有: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1为必胜点.也就是说左上角是1,这样扩散出去. 答案就是所有1位置的概率和. 题解:点击打开链接 Problem B easy problem 因为k很小 公式: ((dep[y]-dep[x])%k+1)*val 当确定depx