60分做法
枚举。注意开long long。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,e,d, p,q;
inline void cal(){
for(int i=1;i*i<=n;i++){
if(n%i == 0){
p = i;
q = n/i;
if(e*d == (p-1)*(q-1)+1){
printf("%d %d\n",p,q);
return;
}
}
}
printf("NO\n");
}
signed main() {
int k;scanf("%lld",&k);
while(k--){
scanf("%lld%lld%lld",&n,&e,&d);
cal();
}
return 0;
}
AC做法
推公式计算,数据范围记 m = n − e ∗ d + 2 m = n-e*d+2 m=n−e∗d+2 其实就是提示。
e ∗ d = ( p − 1 ) ∗ ( q − 1 ) + 1 p ∗ q − ( p + q ) + 2 → p + q = p ∗ q − e ∗ d + 2 = n − e ∗ d + 2 = m e*d = (p-1)*(q-1)+1 p*q - (p+q) +2\to p+q = p*q-e*d+2 = n - e*d+2 = m e∗d=(p−1)∗(q−1)+1p∗q−(p+q)+2→p+q=p∗q−e∗d+2=n−e∗d+2=m
p − q = ( p + q ) 2 − 4 ∗ p q = m 2 − 4 ∗ n p-q = \sqrt{(p+q)^2-4*pq} = \sqrt{m^2-4*n} p−q=(p+q)2−4∗pq=m2−4∗n
解方程组:
{
p
−
q
=
m
2
−
4
∗
n
p
+
q
=
m
\begin{cases} p-q = \sqrt{m^2-4*n} \\ p+q = m \end{cases}
{p−q=m2−4∗np+q=m
得
{
p
=
m
−
t
2
,
t
=
m
2
−
4
∗
n
q
=
m
+
t
2
\begin{cases} p = \frac{ m-t} {2} , t = \sqrt{m^2-4*n}\\ q = \frac{m+t}{2} \end{cases}
{p=2m−t,t=m2−4∗nq=2m+t
注意几个细节:
- t < 0时无解
- p、q都是正整数,且 p <= q
- double存在精度问题,最后要加一个判断
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,e,d,p,q;
inline void cal(){
int m = n-e*d+2;
int t = m*m-4*n;
if(t<0) {printf("NO\n");return;}
p = (m-sqrt(t))/2,q=(m+sqrt(t))/2;
if(p>0 && q>0 && p*q == n && (p-1)*(q-1)+1 == d*e){
printf("%ld %ld\n",p,q);
}else{
printf("NO\n");
}
}
signed main() {
int k;scanf("%lld",&k);
while(k--){
scanf("%lld%lld%lld",&n,&d,&e);
cal();
}
return 0;
}