反素数
问题描述:
如果一个自然数比所有比它小的自然数的约数个数都要多,那么我们就称这个数为一个反素数。例如,1、2、4、6、12和24都是反素数。
任务:
请写一个程序:
l 在文本文件ant.in中读入一个自然数n;
l 找出不大于n的最大的反素数;
l 将结果输出到文本文件ant.out中。
输入格式:
在文件ant.in中应该只包含一行,为一个自然数n,1 £ n £ 2000000000。
输出格式:
你应该在文件ant.out中输出唯一的一个整数——不大于n的最大反素数。
〖输入输出样例〗:
Ant.in | Ant.out |
1000
| 840
|
【结题报告】:
求[1..N]中约数最大的反素数-->求约数最多的数
如果求约数的个数 756=2^2*3^3*7^1
(2+1)*(3+1)*(1+1)=24
基于上述结论,给出算法:按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子
为了剪枝:
性质一:一个反素数的质因子必然是从2开始连续的质数.
因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
/******************************************************************************************************
** Copyright (C) 2011.07.01-2013.07.01
** Author: famousDT <13730828587@163.com>
** Edit date: 2011-10-27
******************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>//abs,atof(string to float),atoi,atol,atoll
#include <math.h>//atan,acos,asin,atan2(a,b)(a/b atan),ceil,floor,cos,exp(x)(e^x),fabs,log(for E),log10
#include <vector>
#include <queue>
#include <map>
#include <time.h>
#include <set>
#include <list>
#include <stack>
#include <string>
#include <iostream>
#include <assert.h>
#include <string.h>//memcpy(to,from,count
#include <ctype.h>//character process:isalpha,isdigit,islower,tolower,isblank,iscntrl,isprll
#include <algorithm>
using namespace std;
typedef long long ll;
#define MY_PI acos(-1)
#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))
#define MY_MALLOC(n, type) ((type *)malloc((n) * sizeof(type)))
#define MY_ABS(a) (((a) >= 0) ? (a) : (-(a)))
#define MY_INT_MAX 0x7fffffff
/*==========================================================*\
| noip-test2
\*==========================================================*/
const ll prime[16] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
ll maxsum, bestnum, n;
void dfs(ll num, ll k, ll sum, ll limit)
//num:当前枚举到的数,k:枚举到的第k大的质因子;sum:该数的约数个数;limit:质因子个数上限;
{
int i;
ll tmp;
if (sum > maxsum) {
maxsum = sum;
bestnum = num;//如果约数个数更多,将最优解更新为当前数;
}
if (sum == maxsum && bestnum > num) {//如果约数个数相同,将最优解更新为较小的数;
bestnum = num;
}
if (k > 15) return ;
tmp = num;
for (i = 1; i <= limit; ++i) {//开始枚举每个质因子的个数
if (tmp * prime[k] > n) {
break;
}
tmp *= prime[k];//累乘到当前数
dfs(tmp, k + 1, sum * (i + 1), i);//继续下一步搜索
}
}
int main()
{
FILE *in, *out;
in = freopen("ant.in", "r", stdin);
out = freopen("ant.out", "w", stdout);
ll i, j;
cin>>n;
dfs(1, 1, 1, 50);
printf("%lld\n", bestnum);
system("pause");
return 0;
}