hdu 4228 Flooring Tiles DFS

//求出最小的x使得x的因子数为2*n,或者2*n-1;
//也就是求出最小的x使得x的因子数为k(k为2*n或者2*n-1);
//素数表 prime{0,2,3,5,7,11,13,17,19};
//如果一个数num = prime ^ (2 * n - 1) (基数的情况) 则它的因子数为 2 * n ;
//如果一个数num = prime ^ (2 * n    ) (偶数的情况) 则它的因子数为 2 * n + 1; (prime 是一个质素);
//现在知道因子数为k , k = k1 * k2 * k3 * ... * kn;

//则x = prime[1]^( k1 - 1 ) * prime[2] * ( k2 - 1 ) * prime[3] * ( k3 - 1 ) * ... * prime[n] * ( kn - 1 );

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4228

//求出最小的x使得x的因子数为2*n,或者2*n-1;
//也就是求出最小的x使得x的因子数为k(k为2*n或者2*n-1);
//素数表 prime{0,2,3,5,7,11,13,17,19};
//如果一个数num = prime ^ (2 * n - 1) (基数的情况) 则它的因子数为 2 * n ;
//如果一个数num = prime ^ (2 * n    ) (偶数的情况) 则它的因子数为 2 * n + 1; (prime 是一个质素);
//现在知道因子数为k , k = k1 * k2 * k3 * ... * kn;
//则x = prime[1]^( k1 - 1 ) * prime[2] * ( k2 - 1 ) * prime[3] * ( k3 - 1 ) * ... * prime[n] * ( kn - 1 );

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

long long prime[10] = {0,2,3,5,7,11,13,17,19,23};
//因为75 < 2 ^ 7 所以不需要很大的质数表;
long long ans;
//记录答案;

long long fast_pow(int x,int k) {
	long long base = x;
	long long ans = 1;
	while(k) {
		if(k & 1) ans *= base;
		base *= base;
		k >>= 1;
	}
	return ans;
}

void DFS(int depth,int ret,long long tot) {
	//depth 是当前的深度,代表prime[depth] * ki;
	//ret是代表还有多少剩下;
	//tot是代表当前的总数;
	//printf("tot : %d %lld\n",depth,tot);
	if(depth>8) return ;
	if(tot <= 0) return ;
	if(ret == 1) {
		ans = min(ans,tot);
		return;
	}
	for(long long i = ret ; i >= 2 ; i --) {
		if(ret % i == 0) {
			//用掉了 i ;
			//printf("i : %d %d\n",depth,i);
			//pow函数有误差,哭晕,调了好久之后,还是自己写了一个;
			DFS(depth+1,ret/i,tot * fast_pow(prime[depth] , ( i - 1 ) ) );
		}
	}

}

long long f[75];

void Deal_with() {
	for(int i = 1 ; i <= 75 ; i ++) {
		ans = (long long ) 1 << 60;
		DFS(1,2*i,1);
		DFS(1,2*i-1,1);
		//printf("%lld\n",ans);
		f[i] = ans;
	}
	int n ;
	while(scanf("%d",&n),n) {
		printf("%lld\n",f[n]);
	}

}

int main(void) {
	//freopen("a.in","r",stdin);
	Deal_with();
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值