题目描述
小T作为班级的班长,承担着班级的各项事务,今天班主任交给了小T一个重要的任务,学校的音乐会就要开始了,要小T帮忙协助开幕式,开幕式正在进行,有2个队伍正在列队,人数分别为a和b,其中a≤b, 为了使得两个队伍的同学的便于列队,需要控制a和b的最小公倍数是x,但是小T想让b尽可能的小,也就是人数较多的队伍人数尽可能少,由于这个问题太难了,小T才小学一年级,还算不过来,需要你帮帮他。
输入格式
第一行一个整数x表示两个队伍人数的最小公倍数。
输出格式
一行用空格隔开的两个数a和b,其中a≤b。
样例数据
样例输入#1
2
样例输出#1
1 2
样例输入#2
6
样例输出#2
2 3
数据范围
对于30%的数据,1≤x≤10^3。
对于50%的数据,1≤x≤10^6。
对于100%的数据,1≤x≤10^12。
---------------------------------------------------------------------------------------------------------------------------------
思路
数论题,分析一波,首先,数据大,时间复杂度最好不要太高,然后,你要会算最小公倍数
知道这些,好,你已经会做这道题了
我们直接枚举a,b就不用枚举了,b=n/a,我们枚举a的范围是什么?我们想,a肯定是在1到n这个范围内,但这个范围太大了,很容易就会超时(我也没试过,不知道会不会超)
我们可以尝试缩小范围
我们先来找一下18的a和b
18
=1*18
=2*9
=3*6
=6*3
=9*2
=18*1
我们发现,18一共有6种方式可以乘出18,其中,2*9就是18的a和b
我们仔细观察,6种方式中,有三种是重复的比如3*6和6*3是一样的,
所以,我们枚举a的时候,可以像判断质数一样,只枚举到sqrt(n)就好了
---------------------------------------------------------------------------------------------------------------------------------
代码来喽:
#include<bits/stdc++.h>
using namespace std;
typedef long long l;
l n,a,b,c;
bool prime(l k) {//判断k是否为质数
for(int i=2; i<=sqrt(k); i++) {
if(k%i==0)
return 0;
}
return 1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
if(prime(n)) {//如果是质数
cout<<1<<" "<<n;//因为质数只有两个因数,所以直接输出
} else {
l i=sqrt(n);
l j=n/i;
//i表示第一个数,j表示第二个数
for(; i>=1; i--,j=n/i) {//从sqrt(n)开始找,也能找到
if((i*j/__gcd(i,j))==n)//如果最小公倍数等于n
break;//结束循环
}
cout<<i<<" "<<j;//果断输出答案
}
return 0;
}