HDU 4542 小明系列故事——未知剩余系
2015-06-26 11:07
239 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4542
参考了ACdreamer的博客:http://blog.csdn.net/ACdreamers/article/details/25049767
首先对于本题
(1)Type = 0即求解约数个数为K结果是一定存在,只不过存在超出范围和不超出范围两种情况,这个与反素数有关,采用dfs+剪枝的搜索
(2)Type = 1即求解约数个数为N-K的最小的数,我们很容易知道对于一个数N,它的约数的个数<=2*sqrt(N),因此对于K<=50000,我们完全可以预处理出前60000的约数个数,来求解该问题,对于>60000,N-2*sqrt(N) > K,我们便不需要考虑。
因此我们很容易写出下面的程序:
参考了ACdreamer的博客:http://blog.csdn.net/ACdreamers/article/details/25049767
首先对于本题
(1)Type = 0即求解约数个数为K结果是一定存在,只不过存在超出范围和不超出范围两种情况,这个与反素数有关,采用dfs+剪枝的搜索
(2)Type = 1即求解约数个数为N-K的最小的数,我们很容易知道对于一个数N,它的约数的个数<=2*sqrt(N),因此对于K<=50000,我们完全可以预处理出前60000的约数个数,来求解该问题,对于>60000,N-2*sqrt(N) > K,我们便不需要考虑。
因此我们很容易写出下面的程序:
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <vector> #include <string> #include <algorithm> #include <functional> using namespace std; typedef long long ll; const int maxn = 60010; const ll inf = (1LL<<62)+1; int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; bool is_prime[maxn]; int prime[maxn]; int val[maxn]; int len; int K; ll ans; void init() { int i, j; len = 0; memset(is_prime, true, sizeof(is_prime)); for(i = 4; i < maxn; i += 2) is_prime[i] = false; prime[len++] = 2; for(i = 3; i * i <= maxn; i += 2) { if(is_prime[i]) { prime[len++] = i; for(j = i * i; j < maxn; j += i) { is_prime[j] = false; } } } for( ; i < maxn; i += 2) { if(is_prime[i]) { prime[len++] = i; } } } int get_factor(int x) { int ans = 1; for(int i = 0; i < len && prime[i] * prime[i] <= x; ++i) { if(x % prime[i] == 0) { int cnt = 0; while(x % prime[i] == 0) { x /= prime[i]; cnt++; } ans *= (cnt + 1); } } if(x > 1) ans *= 2; return ans; } void solve() { memset(val, 0x3f3f3f3f, sizeof(val)); for(int i = 1; i < maxn; ++i) { int cnt = get_factor(i); val[i-cnt] = min(val[i-cnt], i); } } void dfs(int pos, int lim, ll cur, ll num) { if(pos > 15) return ; if(num > K) return ; if(num == K) { ans = min(ans, cur); return ; } for(int i = 1; i <= lim; ++i) { if(ans/p[pos] < cur || num*(i+1) > K) break; if(K%(num*(i+1)) == 0) { dfs(pos + 1, i, cur * p[pos], num*(i+1)); } cur *= p[pos]; } return ; } int main() { //freopen("aa.in", "r", stdin); init(); solve(); int T, type; int kcase = 0; scanf("%d", &T); while(T--) { kcase++; scanf("%d %d", &type, &K); printf("Case %d: ", kcase); if(type == 1) { if(val[K] >= 0x3f3f3f3f) { printf("Illegal\n"); } else { printf("%d\n", val[K]); } } else { ans = inf; dfs(0, 62, 1, 1); if(ans >= inf) { printf("INF\n"); } else { printf("%I64d\n", ans); } } } return 0; }
相关文章推荐
- 程序员开发过程中基本注意点
- 【Linux】设置环境变量
- Android onTouchEvent, onClick及onLongClick的调用机制
- js不验证
- 在一个循环中删除一个列表中的元素
- Android模拟产生事件
- Poj3295 Tautology
- iOS 9适配系列教程:后台定位
- 隐藏在左侧的jquery弹性弹出菜单
- oracle 清除表空间
- mysql数据库操作
- leetcode[165]:Compare Version Numbers
- 关于TabLayout+ViewPager组合实现多页面滑动
- Fibonacci Again
- tcprstat工具安装与使用
- 【IE bug 解决办法】IE下(IE10及以下)当元素为absolute定位时,点击事件失效的解决办法
- hibernate根据映射文件生成数据库对象
- linux防僵尸进程的学习总结
- 绩效沟通-BEST原则
- Android开发框架androidannotations的使用