Codeforces Round #655 (Div. 2) B. Omkar and Last Class of Math

B. Omkar and Last Class of Math

题目链接-B. Omkar and Last Class of Math
Codeforces Round #655 (Div. 2) B. Omkar and Last Class of Math_第1张图片
Codeforces Round #655 (Div. 2) B. Omkar and Last Class of Math_第2张图片
题目大意
给你一个数 n n n,求两个数 a , b a,b a,b,使得 a + b = n a+b=n a+b=n l c m ( a , b ) lcm(a,b) lcm(a,b)尽可能的小

解题思路

  • 假设 a < = b a<=b a<=b,那么 l c m lcm lcm一定大于等于 b b b,且是 b b b a a a的倍数,且 b b b一定小于 n n n,此时我们保证 b b b a a a的倍数,这样 l c m ( a , b ) = b < n lcm(a,b)=blcm(a,b)=b<n,所以只要保证 b b b尽可能小,就能保证 l c m lcm lcm尽可能小了
  • 要想保证 b b b尽可能小,我们只需保证 a a a尽可能大,就是让 a , b a,b a,b尽可能靠近
  • 所以我们可以从 2 2 2开始枚举,枚举到 s q r t ( n ) sqrt(n) sqrt(n),如果 n n n m o d mod mod i = 0 i=0 i=0,说明 n n n可以被分为 i i i份,令 a a a 1 1 1 n / i n/i n/i b b b n − 1 n-1 n1 n − n / i n-n/i nn/i即可
  • 因为是从小到大枚举,满足 n n n m o d mod mod i = 0 i=0 i=0 i i i越小就说明 a , b a,b a,b越接近,所以枚举到满足条件的 i i i直接输出 n / i n/i n/i n − n / i n-n/i nn/i然后退出循环即可
  • 如果没有满足条件的 i i i,说明 n n n为素数,此时输出 1 , n − 1 1,n-1 1,n1即可
  • 具体操作见代码

附上代码

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=2e5+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int m=sqrt(n);
		bool ass=0;
		for(int i=2;i<=m+2&&!ass;i++){
			if(n%i==0){
				cout<<n/i<<" "<<n-n/i<<endl; 
				ass=1;
			}
		}
		if(!ass) cout<<1<<" "<<n-1<<endl;
	} 
	return 0;
}

你可能感兴趣的:(codeforces)