题目
给你一个数X , 求出两个数a b 使得lcm(a,b) == X 且 max(a,b) 最小 。
题解思路
首先 a b 肯定要互质 才能不含多的质因子来构成X,即相乘构成。
这样我们直接用试除法 , 对X的所有质因子筛出,然后判断两边是否互质,因为试除法是根号级别的而且试除法中i在不断变大并且只到根号X,这样另一边就是不断变小的。
所以符合条件的最后一个数就是答案。
如果我们不知道这个结论就只能弄出所有质因子,将他们组合成答案。
质因子不会很多,不超过50个。所以可以进行爆搜出最小的组合方式。
AC代码
结论
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<long long , long long >
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
long long x , p ,ans = 1 ;
cin >> x ;
p = x ;
for (long long i = 2 ; i * i <= p ; i++ )
{
if ( p % i == 0 && __gcd(i,p/i) == 1 )
ans = i ;
}
cout << ans << " " << x/ans << "\n" ;
return 0 ;
}
爆搜参考虎神代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long N,NN,lst[50],R;
int M;
void dfs(int i,long long o){
if(i==M){
if(o<(NN/o)) o=NN/o;
R=min(R,o);
return;
}
dfs(i+1,o);
dfs(i+1,o*lst[i]);
}
int main(){
scanf("%lld",&N);NN=N;R=N;
for(long long i=2;i*i<=N;i++){
if(N % i == 0){
lst[M]=1;
while(N % i == 0) lst[M]*=i,N/=i;
++M;
}
}
if(N!=1) lst[M++]=N;
dfs(0,1);
printf("%lld %lld",NN/R,R);
return 0;
}