忠告1:要学会计算时间复杂度!!
忠告2:要学会抓事实,不要掉进题目直观模拟的陷阱里
事实
1.任意k个数的 \(gcd\) 一定可以是这k个数的最小值,这里以 \(k=3\) 举例
假设 \(gcd(a_1,a_2,a_3)=m\) ,则 \(a_1=k_1m,a_2=k_2m,a_3=k_3m\),其中 \(k_1,k_2,k_3\) 都是整数
那么可以通过移项变成 \(a_1=(k_1+k_3-1)m,a_2=k_2m,a_3=m\)
2.将n分成k个数的和,这k个数中的最小值 \(a_{min} \le \frac{n}{k}\) 对任何n,k都成立
很显然啊,拿 \(k=2\) 的情况举个例子就很明显了,\(k\) 推广开来也是一样的
3.根据事实12,当 \(a_{min}\) 是 \(n\) 的因子时,答案就是 \(a_{min}\)
于是我们可以 \(put\ it\ into\ simple\ words:\) ,找出 \(n\) 的小于 \(\frac{n}{k}\) 的 最大因子
判断时间复杂度
最坏情况: \(t=10^3,n=10^8,k=1\) , $10^{11} > 10^8 $
直接从 \(\frac{n}{k}\) 开始往下遍历很大概率T
我们考虑优化
由于答案一定是 \(n\) 的因子,而因子成对出现(包括1和自身),所以我们开根号找因子,每找一个因子相当于找到两个因子,对每个因子进行判断是否小于 \(\frac{n}{k}\)
此时 最坏情况 \(10^7\)
\(Code\)
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while(t--) {
int n, k;
cin >> n >> k;
int result = 1;
for(int i = 1; i <= sqrt(n); i++) {
if(n % i == 0) {
if(i <= n / k) result = max(result, i);
if(n / i <= n / k) result = max(result, n / i);
}
}
cout << result << endl;
}
return 0;
}
标签:10,frac,Problemset,min,int,cin,因子,Balanced
From: https://www.cnblogs.com/pure4knowledge/p/17993056