第三题:反素数(我的模板)(NOIP2009模拟测试题)

来源:互联网 发布:如何调试动态加载的js 编辑:程序博客网 时间:2024/05/25 16:37
 

 反素数

问题描述:

如果一个自然数比所有比它小的自然数的约数个数都要多,那么我们就称这个数为一个反素数。例如,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;}