BZOJ 1053: [HAOI2007]反素数ant (DFS)

1053: [HAOI2007]反素数ant

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 2543   Solved: 1430
[ 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

HINT

Source

[ Submit][ Status][ Discuss]

因为到素数从小到大乘到23之后就大于2000 000 000了

所以只用考虑10个素数的情况

而且每个素数的个数都是非递增的

然后dfs一下打出反素数的表即可

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10005;
struct node
{
    long long v;
    int hav;
} p[1000005];
int pr[]= {0,2,3,5,7,11,13,17,19,23,27,31};
int num[15],cnt,tot,n;
int ans[1000005];
void dfs(int st,int hav,long long now)
{
    if(now>2000000000) return ;
    if(st>12)
    {
        if(now<=2000000000)
        {
            p[++cnt].hav=hav;
            p[cnt].v=now;
        }
        return ;
    }
    for(int i=0; i<=num[st-1]; i++)
    {
        num[st]=i;
        dfs(st+1,hav*(i+1),now);
        now*=pr[st];
        if(now>2000000000) return ;
    }
}
bool cmp(node a, node b)
{
    return a.v<b.v;
}
int main()
{
    int i,j,q;
    num[0]=100;
    cnt=0;
    tot=0;
    dfs(1,1,1);
    sort(p+1,p+1+cnt,cmp);
    int now=0;
    for(i=1; i<=cnt; i++)
    {
        if(now<p[i].hav)
        {
            ans[++tot]=p[i].v;
            now=p[i].hav;
        }
    }
    while(~scanf("%d",&n))
    {
        for(i=68; i>=1; i--)
            if(n>=ans[i])
            {
                printf("%d\n",ans[i]);
                break;
            }
    }
    return 0;
}


你可能感兴趣的:(BZOJ 1053: [HAOI2007]反素数ant (DFS))