题意:

  给你一个数,求在多少种不同的进制下这个数每一位都是3、4、5、6中的一个。

 

思路:  

  搜索。枚举这个数在任意进制下的表示,判断是否合法。当数字只有3、4、5、6时,必定有无穷种。

  因为数字太大,所以直接枚举必定会超时。

  下面有两种剪枝的方法:

    1. 先枚举最后一位的情况。 假设数字n在base进制下表示为 a[n]...a[0],即 n = a[0] + a[1]*base^1 + ... + a[n]*base^n。

   则 n - a[0] = a[1]*base^1 + ... + a[n]*base^n = base * (a[1] + ... + a[n]*base^(n-1) )。 即n - a[0] 是base 的倍数。

   所以,我们可以确定base是n-a[0]的因子。 所以,我们可以先枚举在某个进制下的末位a[0],然后在枚举 n-a[i]的因子就好了。

  代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <algorithm>
  7 #include <string>
  8 #include <queue>
  9 #include <stack>
 10 #include <vector>
 11 #include <map>
 12 #include <set>
 13 #include <functional>
 14 #include <time.h>
 15 
 16 using namespace std;
 17 
 18 typedef __int64 ll;
 19 
 20 const int INF = 1<<30;
 21 const int MAXN = (int) 1e6+5;
 22 
 23 int Prime[MAXN], len;
 24 bool is[MAXN];
 25 
 26 ll f[20];
 27 int cnt[20], num;
 28 
 29 void factor(ll x) { //分解质因数
 30     num = 0;
 31     if (x==1) return ;
 32     for (int i = 0; i < len; i++) if ((x%Prime[i])==0) {
 33         f[num] = Prime[i];
 34         cnt[num] = 0;
 35         while (x%Prime[i]==0) {
 36             x /= Prime[i];
 37             cnt[num]++;
 38         }
 39         num++;
 40         if (x==1) break;
 41         if (x<Prime[len-1] && !is[x]) break;
 42     }
 43     if (x!=1) {
 44         f[num] = x;
 45         cnt[num++] = 1;
 46     }
 47 }
 48 
 49 ll n;
 50 int ans;
 51 
 52 void dfs(ll base, int deep) { //枚举可以重复的组合
 53     if (deep==num) {
 54         if (base < 4) return ;
 55         ll tmp = n, t;
 56         while (tmp) {
 57             t = tmp%base;
 58             if (!(2<t&&t<7)) return ;
 59             tmp /= base;
 60         }
 61         ans++;
 62         return ;
 63     }
 64     ll tmp = base;
 65     for (int i = 0; i <= cnt[deep]; i++) {
 66         dfs(tmp, deep+1);
 67         tmp *= f[deep];
 68     }
 69 }
 70 
 71 void solve() {
 72     scanf("%I64d", &n);
 73     ans = 0;
 74     if (2<n&&n<7) {
 75         puts("-1");
 76         return ;
 77     }
 78     for (int i = 3; i < 7; i++) if (n-i>10) { //枚举末位
 79         factor(n-i);
 80         dfs(1LL, 0);
 81     }
 82     printf("%d\n", ans);
 83 }
 84 
 85 int main() {
 86     #ifdef Phantom01
 87         freopen("HDU4937.in", "r", stdin);
 88     #endif //Phantom01
 89 
 90     memset(is, false, sizeof(is));
 91     len = 0;
 92     for (int i = 2; i < MAXN; i++) if (!is[i]) {
 93         Prime[len++] = i;
 94         for (ll j = i*2; j < MAXN; j+=i)
 95             is[j] = true;
 96     }
 97 
 98     int T;
 99     scanf("%d", &T);
100     for (int i = 1; i <= T; i++) {
101         printf("Case #%d: ", i);
102         solve();
103     }
104 
105     return 0;
106 }
View Code

相关文章: