HDU 4937 Lucky Number 搜索
题意:
给你一个数,求在多少种不同的进制下这个数每一位都是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 搜索的更多相关文章
- 枚举 + 进制转换 --- hdu 4937 Lucky Number
Lucky Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- 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 求出 ...
- HDU 4937 Lucky Number (数学,进制转换)
题目 参考自博客:http://blog.csdn.net/a601025382s/article/details/38517783 //string &replace(iterator fi ...
- 2014多校第七场1003 || HDU 4937 Lucky Number
题目链接 题意 : 给定一个十进制n,让你转化成某个进制的数,让这个数只包含3 4 5 6这些数字,这个进制就成为n的幸运数字,输出有多少幸运数字,例如19,5进制表示是34,所以5是19的一个幸运数 ...
- hdu 4937 Lucky Number
虽然算法清晰的不能再清晰,但是实现总是边角料错这错那. 题目大意: 给出n,找出一些进制,使得n在该进制下仅为3,4,5,6表示 解题思路: 首先,4-10000进制直接枚举计算出每一位 此外,最多只 ...
- HDU 4937 Lucky Number 规律题_(:зゝ∠)_
把全部合法的进制打出来会发现合法的进制都是在 n/3 n/4 n/5的边上 然后暴力边上的进制数.. #include <cstdio> #include <set> type ...
- HDOJ 4937 Lucky Number
当进制转换后所剩下的为数较少时(2位.3位),相应的base都比較大.能够用数学的方法计算出来. 预处理掉转换后位数为3位后,base就小于n的3次方了,能够暴力计算. . .. Lucky Numb ...
- HDU 3346 Lucky Number
水题 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> us ...
- CF1478-B. Nezzar and Lucky Number
CF1478-B. Nezzar and Lucky Number 题意: 题目给出一个数字\(d(1\leq d \leq 9)\)代表某个人最喜欢的数字. 题目定义了幸运数字,它的含义为:若一个数 ...
随机推荐
- TLCL
参考阅读:http://billie66.github.io/TLCL/book/chap04.html 绝对路径 An absolute pathname begins with the root ...
- POJ 1182 食物链 【并查集】
解题思路:首先是没有思路的----然后看了几篇解题报告 http://blog.csdn.net/ditian1027/article/details/20804911 http://poj.org/ ...
- Set集合[HashSet,TreeSet,LinkedHashSet],Map集合[HashMap,HashTable,TreeMap]
------------ Set ------------------- 有序: 根据添加元素顺序判定, 如果输出的结果和添加元素顺序是一样 无序: 根据添加元素顺序判定,如果输出的结果和添加元素的顺 ...
- Collectio集合,List《ArrayList,LinkedList》
集合: Collection类 package com.collection.demo; import java.util.ArrayList; import java.util.Arrays; im ...
- B. Recursive Queries 打表
Code: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...
- 路飞学城Python-Day5
48.字典的类型的详细方法字典的增加值dic["k1"] = "v1"字典的修改dic["k2"] = "v2"判断是否 ...
- /www: target is busy. 解决卸载磁盘目录繁忙的问题
umount /www 卸载磁盘遇到 以下问题 umount: /www: target is busy. (In some cases useful info about processes tha ...
- python学习笔记第三章
1.列表是由一系列特定顺序排列得元素组成,在python中用([])组成,列表得索引是从0开始,不是1 xu=['a','b',''c] print(xu) 访问列表的元素第一个元素 xu=['a', ...
- /application/nginx/sbin/nginx -h
[root@web03 ~]# /application/nginx/sbin/nginx -h nginx version: nginx/1.6.3Usage: nginx [-?hvVtq] [- ...
- John Morgan:黎曼几何、曲率、Ricci流以及在三维流形上的应用二讲
本文是笔者在线看Lektorium上John Morgan在圣彼得堡国立大学欧拉研究所的讲座做的笔记.第一讲以如下内容组成 1. 黎曼曲面上的联络 黎曼流形$(M^n,g)$中,$M$为$n$维流形, ...