【 TIMUS-1748】【数学+搜索】The Most Complex Number【求反素数,数据范围较大】

来源:互联网 发布:我的世界手机枪械js 编辑:程序博客网 时间:2024/05/21 16:56

传送门:http://acm.timus.ru/problem.aspx?space=1&num=1748

描述:

1748. The Most Complex Number

Time limit: 1.0 second
Memory limit: 64 MB
Let us define a complexity of an integer as the number of its divisors. Your task is to find the most complex integer in range from 1 to n. If there are many such integers, you should find the minimal one.

Input

The first line contains the number of testcases t (1 ≤ t ≤ 100). The i-th of the following t lines contains one integer ni (1 ≤ ni ≤ 1018).

Output

For each testcase output the answer on a separate line. The i-th line should contain the most complex integer in range from 1 to ni and its complexity, separated with space.

Sample

inputoutput
5110100100010000
1 16 460 12840 327560 64
Problem Author: Petr Lezhankin
Problem Source: Ufa SATU Contest. Petrozavodsk Summer Session, August 2009
Tags: number theory  (
hide tags for unsolved problems
)

题意;

给定一个数n,要求一个不超过n的数,并且因子数最多的最小的数。 


思路:

就是求反素数

根据反素数的性质,每个反素数必然是由一系列连续质因子组成,并且较小的因子的次数一定比较大的因子的次数大 (不满足这两个条件必然可以找到一个 更小的数 且因子数与该数相同 ,矛盾)

dfs搜一下就好了

搜索控制两个条件

1:第k个因子的最高次比k-1的最高次低,即保持指数单调不增,达到剪枝的目的

2:因子数的话,可以根据 定理1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的个数就是,(r1+1)*(r2+1)~(rk+1).来求


搜索过程的话,如果发现当前乘积已经大于n了,就可以break掉

本题数据比较大。 这个判断用乘法会溢出,所以改用除法就好了,或者强制转换为double来乘


代码:

#include <bits/stdc++.h>using  namespace  std;#define ull unsigned long longconst ull inf = ~0ULL;int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};//这16个素数乘起来接近于ull最大值 //因为质因数的指数不递减,所以所以指数为1的时候不爆ull的最多16个质数ull ans, n;int mx;//最多的因数void dfs(int dep, ull tmp, int num, int limit){  //深度,当前数的值,因数的个数,当前质因数的指数  if(tmp > n)return ;  if(num > mx) ans = tmp, mx = num;  //贪心,当因子个数相同时,取值最小的  if(num == mx && ans > tmp) ans = tmp;    for(int i = 1; i <= limit; i++){ //指数单调不增    // double cur = (double) tmp;    if(tmp > n / p[dep])break; //超过n就结束    dfs(dep + 1, tmp *= p[dep], num * (i + 1), i);  } }int  main(){  int t;  cin >> t;  while(t --){    cin >> n;    ans = inf;    mx = 0;    dfs(0, 1, 1, 60);    cout << ans << ' ' << mx << endl;  }  return 0;}





0 0
原创粉丝点击