zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    114     }
    115     return 0;
    116 }
    View Code
      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
    ",dfs(0,1,nct-1,1)-1);
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    Android Intent Flag的介绍
    获得SD卡的剩余容量
    横竖屏判断
    自定义View
    按键事件
    android程序完全退出步骤
    环境变量的配置和虚拟机安装apk文件
    GridView网格布局
    去掉系统title
    获取手机的序列号
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4458555.html
Copyright © 2011-2022 走看看