一本通1625【例 1】反素数 Antiprime
反素数 Antiprime
题目描述
原题来自:POI 2001
如果一个大于等于 1 的正整数 n,满足所有小于 n 且大于等于 1 的所有正整数的约数个数都小于 n 的约数个数,则 n 是一个反素数。譬如:1, 2, 4, 6, 12, 24,它们都是反素数。
请你计算不大于 n 的最大反素数。
输入格式
一行一个正整数 n。
输出格式
只包含一个整数,即不大于 n 的最大反素数。
样例
样例输入
1000
样例输出
840
数据范围与提示
对于 10% 的数据,1≤n≤103;
对于 40% 的数据,1≤n≤106;
对于 100% 的数据,1≤n≤2×109。
sol:题意有点烦,其实就是求不超过n的约数个数最多的最小的数
可以只用2,3,5,7,11,13,17,19,23,29,31爆搜出这个数
这个数就是2t1*3t2*5t3*~~~*31t10,且t1>=t2>=t3>=~~~>=t10
好像dfs挺快的??
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int Prime[]={0,2,3,5,7,11,13,17,19,23,29}; ll n; ll ans_Num=0,ans_Ges=0; inline void dfs(int Now,ll Ges,ll Num,int Up) { if(Ges>ans_Ges) { ans_Num=Num; ans_Ges=Ges; } else if(Ges==ans_Ges&&Num<ans_Num) { ans_Num=Num; } int i; for(i=1;i<=Up;i++) { Num*=Prime[Now]; if(Num>n) return; dfs(Now+1,Ges*(i+1),Num,i); } } int main() { R(n); dfs(1,1,1,31); Wl(ans_Num); return 0; } /* input 1000 output 840 input 354218765 output 294053760 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!