2023莆田暑期集训CSP-J Day7——4、列队2

题目描述

小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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值