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

 

 反素数

问题描述:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值