WIKIOI 2461 反质数

来源:互联网 发布:安卓乐器软件 编辑:程序博客网 时间:2024/06/02 07:30

【问题描述】
一个正整数n 被称为反质数,当且仅当它的因子多余任何一个比它小的正整数。
前6 个反质数分别是:1,2,4,6,12 和24
你的任务是设计一个程序,读入正整数n,找到比n 小的最大的反质数。

【输入格式】
* 第1 行: 1 个正整数:n (1<=n<=2,000,000,000)
【输入样例】
1000
【输出格式】
* 第1 行: 输出比n 小的最大的反质数
【输出样例】
840

 

对于一个数m 统计它的因数的个数

将m进行分解质因数

m=(p1^a1)*(p2^a2)*......*(pn^an)

那么它的因数个数为 (a1+1)*(a2+1)*......*(an+1)

 

对于p1<p2<p3<......<pn

有a1<=a2<=a3<=......<=an

如果有a2<a1

则令m'=(p1^a2)*(p2^a1)*......*(pn^an)

m'<m=(p1^a1)*(p2^a2)*......*(pn^an)

且m'和m的因数个数相同

所以可以dfs搜索

 

#include<iostream>#include<cstdio>using namespace std;const int table[9]={0,2,3,5,7,11,13,17,19};  //dfs 8int s[11];long long ans=1;long long z;long long m;long long last;long long quick(int s,int i){     long long ret=1;     while(i)     {             i--;             ret*=s;     }     return ret;}void dfs(int i){     int a;          if(i==0)     {             if(ans<m)             {                                      long long t=1;                   for(a=1;a<=8;a++)                   if(s[a]!=0)                   t=t*(s[a]+1);                                      if(t>z||(t==z&&ans<last))                   {                       z=t;                       last=ans;                   }                                                                              }             return;     }          if(ans>=m)return;          for(int k=0;;k++)     {             long long mi=quick(table[i],k);             if(ans*mi>=m)return;             s[i]=k;             ans*=mi;             dfs(i-1);             ans/=mi;     }}                          int main(){     cin>>m;       dfs(8);       cout<<last<<'\n';       return 0;}