这个做法任然被 hack掉了,但是有利于锻炼深搜
/*
一般如果题目中给了两种情况,
一种是easy的有可能用暴力(深搜)
像本题,我就没想到还可以把质因数一个一个存进数组去
一开始印象是觉得这样非常大,不太可行
*/
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PLL;
const int N=2e5+10;
//LL ansx=1,ansy==1;
LL a,b,c,d;
LL aa,bb;
//[a,c],[b,d]
LL resx,resy;
LL C[N];
LL m;
bool flag;
void dfs(int idx,LL ansx,LL ansy)
{
if(flag) return;
if(idx==m+1)
{
LL ax=(c/ansx)*ansx;
LL ay=(d/ansy)*ansy;
if(ax>aa&&ay>bb)
{
resx=ax;
resy=ay;
flag=true;
return;
}
//第二种情况,ax和ay互换一下
ax=(c/ansy)*ansy;
ay=(d/ansx)*ansx;
if(ax>aa&&ay>bb)
{
resx=ax;
resy=ay;
flag=true;
return;
}
return;
}
LL p=C[idx]; //取出当下质因数
if(ansx>c||ansy>d)
{
return;
}
dfs(idx+1,ansx*p,ansy);
dfs(idx+1,ansx,ansy*p);
}
void solve()
{
cin>>a>>b>>c>>d;
aa=a;
bb=b;
unordered_map<LL,LL> mp;
//[a,c],[b,d]
/*
最终的结果是:x*y=k*a*b;
打算先分别对a,b分解质因数
*/
//<一>分解质因数的过程
// vector<PLL> A,B;
for(int i=2;i*i<=a;i++)
{
if(a%i==0)
{
int cnt=0;
while(a%i==0)
{
a/=i;
cnt++;
}
//A.push_back({i,cnt});
mp[i]+=cnt;
}
}
if(a)
{
//A.push_back({a,1});
mp[a]+=1;
}
for(int i=2;i*i<=b;i++)
{
if(b%i==0)
{
int cnt=0;
while(b%i==0)
{
b/=i;
cnt++;
}
//B.push_back({i,cnt});
mp[i]+=cnt;
}
}
if(b)
{
//B.push_back({b,1});
mp[b]+=1;
}
//把两者的质因数都用mp存在一起了,现在把他们调出来
//比如一个质因子p,它有cnt 个,我们应该一个一个把它存入数组中,(为了方便dfs)
for(auto it:mp)
{
LL p=it.x,cnt=it.y;
for(int k=1;k<=cnt;k++)
{
C[++m]=p;
}
}
sort(C+1,C+1+m); //对所有的质因数排个序
//现在要凑成x*y=k*a*b
/*
x的范围是在 [a,c]
y的范围是在 [b,d]
我是打算用dfs凑出x和y的约数ansx,和 ansy
然后用c/ansx下取整 *ansx 求出 >a的最大整数 (保证该整数>a&&<=c)
用 d/ansy 下取整 *asny 求出 >b的最大整数 (保证该整数 >b&&<=d)
*/
dfs(1,1,1);
if(flag) cout<<resx<<" "<<resy<<endl;
else cout<<"-1 -1"<<endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--)
{
flag=false;
m=0;
solve();
}
return 0;
}