思路:
我们可以发现
e
×
d
=
(
p
−
1
)
×
(
q
−
1
)
+
1
变成
p
+
q
=
n
−
e
×
d
+
2
e \times d = (p - 1) \times (q - 1) + 1 \text{变成} p + q = n - e \times d + 2
e×d=(p−1)×(q−1)+1变成p+q=n−e×d+2。我们就可以对其进行二分了。如果你会数学解的话更好,我的二分是参考了一些巨佬的代码才AC的。
AC code:
#include <iostream>
using namespace std;
#define int long long
signed main()
{
int t;
cin >> t;
while(t--)
{
int n,d,e;
cin >> n >> d >>e ;
int t = n - e * d + 2;
int l = 1,r = t / 2 + 1;//只用到它的一半即可
bool flag = false;
while(l <= r)
{
int mid =(l+ r) >> 1;
int tt = t - mid;
if(mid *tt == n)
{
cout << mid << " " << t - mid << endl;//如果可以的话能够中途输出的
flag = true;
break;
}
if((mid) * (tt) < n)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
if(flag)
{
continue;
}
if((l) * (t - l) == n)cout << l << " " << t - l << endl;
else cout << "NO" << endl;//判读无解
}
return 0;
}
另外一种解:
{ p + q = n − e d + 2 p − q = ( n − e × d + 2 ) 2 − 4 × n \begin{cases} p + q = n - ed + 2 \\ p - q = \sqrt{(n - e \times d + 2) ^ 2 - 4 \times n} \end{cases} {p+q=n−ed+2p−q=(n−e×d+2)2−4×n
我们将第一个等式加上第二个等式
{ p = n − e × d + 2 + ( n − e × d + 2 ) 2 − 4 ∗ n 2 q = n − e × d + 2 − ( n − e × d + 2 ) 2 − 4 ∗ n 2 \begin{cases} p = \frac{n - e \times d + 2 + \sqrt{(n - e \times d + 2) ^ 2 - 4 * n}}{2} \\ q = \frac{n - e \times d + 2 - \sqrt{(n - e \times d + 2) ^ 2 - 4 * n}}{2} \end{cases} ⎩ ⎨ ⎧p=2n−e×d+2+(n−e×d+2)2−4∗nq=2n−e×d+2−(n−e×d+2)2−4∗n
输出 min ( p , q ) 和 max ( p , q ) \min(p,q) \text{和} \max(p,q) min(p,q)和max(p,q)。
AC code:
#include <iostream>
#include <cmath>
using namespace std;
#define int long long
signed main()
{
int t;
cin >> t;
while(t--)
{
int n,d,e;
cin >> n >> d >> e;
int p = n - e * d + 2 + sqrt((n - e * d + 2) * (n - e * d + 2) - 4 * n);
int q = n - e * d + 2 - sqrt((n - e * d + 2) * (n - e * d + 2) - 4 * n);
if(p & 1 ||q & 1 || p < 0 || q < 0)//判断是不是正整数
{
cout << "NO" << endl;
}
else
{
cout << min(p / 2,q / 2) << " " << max(p / 2,q / 2) << endl;
}
}
return 0;
}
var code = “a9a2bba2-9ed2-4309-b92c-1f910d07d5a9”