E1. Divisible Numbers (easy version)
题意:已知(a,c]和(b,d],求x属于(a,c]和y属于(b,d],使得x*y%a*b==0
思路:由于easy version是1E5的范围,所以可以枚举x属于(a,c],之后根据x,来确定y
int temp=a*b/(__gcd(a*b,i));
y=b/temp*temp+temp;
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int T;cin>>T;int a,b,c,d;
while(T--){
bool flag=0;cin>>a>>b>>c>>d;
for(int i=a+1;i<=c;i++){
int x=a*b/(__gcd(a*b,i));
x=b/x*x+x;
if(x<=d){flag=1;cout<<i<<" "<<x<<'\n';break;}
}
if(!flag)cout<<-1<<" "<<-1<<'\n';
}
return 0;
}
E2. Divisible Numbers (hard version)
题意同上,范围(1≤a<c≤10E9, 1≤b<d≤10E9)
两种方法:
方法一:把a和b的用根号的复杂度把所有因数求出来,然后先确保x有这些因数的乘积,之后找y
总复杂度是(根号ab大概跑不满),如果直接把a*b的所有因数求出来,拿时间复杂度就是(前一个根号跑满,后一个根号不一定跑满),Test1就TLE了
时间【296ms】
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
vector<int >va,vb;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
int T;cin>>T;int a,b,c,d;
while(T--){
va.clear();vb.clear();
bool flag=0;
cin>>a>>b>>c>>d;
for(int i=1;i*i<=a;i++){
if(a%i==0){
va.push_back(i);
if(a/i!=i)va.push_back(a/i);
}
}
for(int i=1;i*i<=b;i++){
if(b%i==0){
vb.push_back(i);
if(b/i!=i)vb.push_back(b/i);
}
}
for(int i=0;i<va.size();i++){
for(int j=0;j<vb.size();j++){
int k=va[i]*vb[j];
int x=(a/k+1)*k;
if(x>c)continue;
k=a*b/k;
int y=(b/k+1)*k;
if(y>d)continue;
cout<<x<<" "<<y<<'\n';
flag=1;break;
}
if(flag)break;
}
if(!flag)cout<<-1<<" "<<-1<<'\n';
}
return 0;
}
方法二
思路:把a和b的所有质因数以及对应的个数求出来,之后dfs搜索可能的因数,具体实现就是对于当前的数,把取的多少个数(0~个数)一一遍历,作为因数,之后用同样的方法写出x和y
代码:参考:E2. Divisible Numbers (hard version) - AcWing
时间【46ms】