题意:

  给你一个数,求在多少种不同的进制下这个数每一位都是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]的因子就好了。

  代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h> using namespace std; typedef __int64 ll; const int INF = <<;
const int MAXN = (int) 1e6+; int Prime[MAXN], len;
bool is[MAXN]; ll f[];
int cnt[], num; void factor(ll x) { //分解质因数
num = ;
if (x==) return ;
for (int i = ; i < len; i++) if ((x%Prime[i])==) {
f[num] = Prime[i];
cnt[num] = ;
while (x%Prime[i]==) {
x /= Prime[i];
cnt[num]++;
}
num++;
if (x==) break;
if (x<Prime[len-] && !is[x]) break;
}
if (x!=) {
f[num] = x;
cnt[num++] = ;
}
} ll n;
int ans; void dfs(ll base, int deep) { //枚举可以重复的组合
if (deep==num) {
if (base < ) return ;
ll tmp = n, t;
while (tmp) {
t = tmp%base;
if (!(<t&&t<)) return ;
tmp /= base;
}
ans++;
return ;
}
ll tmp = base;
for (int i = ; i <= cnt[deep]; i++) {
dfs(tmp, deep+);
tmp *= f[deep];
}
} void solve() {
scanf("%I64d", &n);
ans = ;
if (<n&&n<) {
puts("-1");
return ;
}
for (int i = ; i < ; i++) if (n-i>) { //枚举末位
factor(n-i);
dfs(1LL, );
}
printf("%d\n", ans);
} int main() {
#ifdef Phantom01
freopen("HDU4937.in", "r", stdin);
#endif //Phantom01 memset(is, false, sizeof(is));
len = ;
for (int i = ; i < MAXN; i++) if (!is[i]) {
Prime[len++] = i;
for (ll j = i*; j < MAXN; j+=i)
is[j] = true;
} int T;
scanf("%d", &T);
for (int i = ; i <= T; i++) {
printf("Case #%d: ", i);
solve();
} return ;
}

    2. 当n在base进制下为一位数的时候,为3、4、5、6,则一定存在无穷种进制下都是这个一位数。

     两位数时, n = a[1]*base + a[0]

     三位数时,n = a[2]*base^2 + a[1]*base + a[0]

    因此,在n是两位数或者三位数时,我们可以枚举这个两位数或者三位数,求得有多少个base能得到这个两位数或三位数。

    当 n 是4位数或者更多时, n = a[0] + a[1]*base^1 + ... + a[n]*base^n > 3*base^4 。即 3*base^4 < n <= 1e12。 所以,此时base < 7000。

    所以,我们可以暴力枚举n是四位数的情况,而这时的base不会大于7000 。所以就不会超时了。

  代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h> using namespace std; typedef __int64 ll;
const int INF = <<; ll n;
int ans; inline int function1(ll a, ll b) { //n = a*base + b
if (((n-b)%a)!=) return ; //如果不是整数
ll tmp = (n-b)/a;
if (a>=tmp || b>=tmp) return ; //如果位数大于进制数
return ;
} inline int function2(ll a, ll b, ll c) { //n = a*base^2 + b*base + c
c -= n;
ll t1 = b*b-*a*c;
if (t1<) return ;
ll t2 = (ll) sqrt((double)t1);
if (t2*t2!=t1) return ;
if (((t2-b)%(*a))!=) return ;
t1 = (t2-b)//a;
if (t1<=a || t1<=b || t1<=c || t1<=) return ;
return ;
} inline bool check(int base) {
ll t = n, cnt = , tt;
while (t>) {
tt = t%base;
if (!(<tt&&tt<)) return false;
t /= base;
cnt++;
}
return cnt>;
} void solve() {
scanf("%I64d", &n); if (<n&&n<) {
puts("-1");
return ;
} ans = ;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
for (int k = ; k < ; k++) {
ans += function2(i, j, k);
}
ans += function1(i, j);
}
}
ll len = min(n, 7000ll);
for (int i = ; i < len; i++)
ans += check(i) ? : ; printf("%d\n", ans);
} void ttt(int i) {
int t = ;
printf("%d:", i);
while (t) {
printf("%d ", t%i);
t /= i;
}
puts("");
} int main() {
#ifdef Phantom01
freopen("HDU4937.in", "r", stdin);
// freopen("HDU4937.txt", "w", stdout);
#endif //Phantom01 int T;
scanf("%d", &T);
for (int i = ; i <= T; i++) {
printf("Case #%d: ", i);
solve();
} return ;
}

HDU 4937 Lucky Number 搜索的更多相关文章

  1. 枚举 + 进制转换 --- hdu 4937 Lucky Number

    Lucky Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)To ...

  2. HDU 4937 Lucky Number(2014 Multi-University Training Contest 7)

    思路:先枚举  a*bas +b = n  求出 bas 在sqrt(n)到n的  (bas>a&&bas>b) 再枚举  a*bas*bas+b*bas+c =n  求出 ...

  3. HDU 4937 Lucky Number (数学,进制转换)

    题目 参考自博客:http://blog.csdn.net/a601025382s/article/details/38517783 //string &replace(iterator fi ...

  4. 2014多校第七场1003 || HDU 4937 Lucky Number

    题目链接 题意 : 给定一个十进制n,让你转化成某个进制的数,让这个数只包含3 4 5 6这些数字,这个进制就成为n的幸运数字,输出有多少幸运数字,例如19,5进制表示是34,所以5是19的一个幸运数 ...

  5. hdu 4937 Lucky Number

    虽然算法清晰的不能再清晰,但是实现总是边角料错这错那. 题目大意: 给出n,找出一些进制,使得n在该进制下仅为3,4,5,6表示 解题思路: 首先,4-10000进制直接枚举计算出每一位 此外,最多只 ...

  6. HDU 4937 Lucky Number 规律题_(:зゝ∠)_

    把全部合法的进制打出来会发现合法的进制都是在 n/3 n/4 n/5的边上 然后暴力边上的进制数.. #include <cstdio> #include <set> type ...

  7. HDOJ 4937 Lucky Number

    当进制转换后所剩下的为数较少时(2位.3位),相应的base都比較大.能够用数学的方法计算出来. 预处理掉转换后位数为3位后,base就小于n的3次方了,能够暴力计算. . .. Lucky Numb ...

  8. HDU 3346 Lucky Number

    水题 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> us ...

  9. CF1478-B. Nezzar and Lucky Number

    CF1478-B. Nezzar and Lucky Number 题意: 题目给出一个数字\(d(1\leq d \leq 9)\)代表某个人最喜欢的数字. 题目定义了幸运数字,它的含义为:若一个数 ...

随机推荐

  1. 引用axiv文献的问题

    首先找了一下对8种常见引用格式进行说明的文章 https://blog.csdn.net/wkd22775/article/details/51798927 然后就是水木社区大神们的记录http:// ...

  2. Git 环境安装

    本文环境: 操作系统:Windows XP SP3 Git客户端:TortoiseGit-1.8.14.0-32bit 一.安装Git客户端 全部安装均采用默认! 1. 安装支撑软件 msysgit: ...

  3. 转:IE 无法使用 js trim() 的解决方法

    http://hi.baidu.com/yuiezt/item/756d0f4ec4d2640ec11613f9   var aa = $("#id").val().trim()  ...

  4. POJ 2367 Genealogical tree【拓扑排序】

    题意:大概意思是--有一个家族聚集在一起,现在由家族里面的人讲话,辈分高的人先讲话.现在给出n,然后再给出n行数 第i行输入的数表示的意思是第i行的子孙是哪些数,然后这些数排在i的后面. 比如样例 5 ...

  5. 接口测试工具篇--jmeter

    jmeter的安装及使用在这里不进行讲解了,网上有很多资料 下面开始讲解如何使用jmeter做http接口测试 在jmeter中添加一个http请求,添加方式:测试计划上邮件添加线程组,线程组上邮件选 ...

  6. WebKit.NET-0.5简单应用

    最近想用c#做个简单的浏览器工具,但是网站一些内容不支持c#内置的WebBowser控件,于是只能改用其他内核浏览器进行开发,搜索到WebKit.NET这个封装好的浏览器引擎,需求的功能也都有,于是用 ...

  7. BZOJ 1085 / LOJ 2151 [SCOI2005]骑士精神 (剪枝/A*迭代搜索)

    题目大意:略 直接爆搜会T,我们优化一下,统计出当前棋盘和目标棋盘不同的位置的数量k,那么当前棋盘变成目标棋盘最少的移动次数是k-1 每次选择一个最大深度ma,那么如果当前走了dep步,显然必须保证d ...

  8. state.sls web.apache

    [root@master01 web]# salt 'node02' state.sls web.apache node02: ----------           ID: apache-inst ...

  9. ProGuard常见问题及解决套路

    ProGuard是一个压缩.优化和混淆Java字节码的工具,非常好用.本篇文章总结一下许多人在使用ProGuard时经常遇到的问题. 我把在使用ProGuard时经常遇到的问题分为两类,分别是导致构建 ...

  10. Eclipse配置class文件输出目录

    1, Eclipse选中项目名称,邮件选中“Build Path”,然后选择“Configure Build Path”--->选择“Source” Tab---->修改"Def ...