1. 程式人生 > >bzoj1053 [HAOI2007]反素數ant

bzoj1053 [HAOI2007]反素數ant

mes inpu discuss 只需要 得到 反素數 ++ 現在 class

1053: [HAOI2007]反素數ant

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3410 Solved: 1989
[Submit][Status][Discuss]

Description

  對於任何正整數x,其約數的個數記作g(x)。例如g(1)=1、g(6)=4。如果某個正整數x滿足:g(x)>g(i) 0<i<x ,則稱x為反質數。例如,整數1,2,4,6等都是反質數。現在給定一個數N,你能求出不超過N的最大的反質數麽 ?

Input

  一個數N(1<=N<=2,000,000,000)。

Output

  不超過N的最大的反質數。

Sample Input

1000

Sample Output

840 分析:這道題讓我們求這樣一個數:1.因數最多 2.如果滿足1條件的有多個,則取最小的那一個. 根據唯一分解定理可以得到:x = p1^k1 * p2^k2 *...*pn^kn,其中p1,p2,...,pn為質數,這樣有多少個因數呢?根據乘法原理,質數p1可以不選,選1個,2個...k1個,p2到pn也是類似,那麽因數個數=(k1 + 1)*(k2 + 1)*...*(kn + 1). 顯然,用小質數比用大質數更好,又因為2*3*5*7*11*13*17*19*23*29=6,469,693,230>2,000,000,000,所以我們只需要用到前9個質數就可以了!這樣,我們搜索每個質數的次數,更新答案就可以了。如果在搜索中數的大小超過了n,就剪枝。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

long long n,ans = 2000000000;
int sushu[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 },a;

void dfs(long long num, int cishu, int cnt)
{
    if (cnt > 9)
        return;
    if (cishu > a)
    {
        ans 
= num; a = cishu; } if (cishu == a && num < ans) ans = num; for (int i = 1; i <= 31; i++) { if (num * sushu[cnt] > n) return; dfs(num * sushu[cnt], cishu *(i + 1), cnt + 1); num *= sushu[cnt]; } } int main() { scanf("%lld", &n); dfs(1, 1, 0); printf("%lld\n", ans); return 0; }

bzoj1053 [HAOI2007]反素數ant