解密 (CSP-J 2022)

解密 (CSP-J 2022)

这个题给了不少变量,显得有一点复杂。需要耐心地做一下数学推导,就会发现其实就是一个一元二次方程:

n=pqn = p \cdot q

m=ned+2=n(p1)(q1)1+2=p+qm = n - e \cdot d + 2 = n - (p - 1) * (q - 1) - 1 + 2 = p + q

所以我们有:

p+n/p=mp+n/p=m

p2mp+n=0p^2-mp+n=0

p=mm24n2p = \frac{m - \sqrt{m^2-4n}}{2}

q=m+m24n2q = \frac{m + \sqrt{m^2-4n}}{2}

然后判断一下根是否是整数,以及是否大于0即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int k;
ll n,d,e;
 
int main() {
 
    scanf("%d", &k);
    while (k--) {
        scanf("%lld %lld %lld", &n, &d, &e);
        ll m = n - e * d + 2;
        ll det = m * m - 4 * n;
        ll sq = sqrt(det);
        if (det < 0 || sq * sq != det || (m - sq) % 2 != 0 || (m + sq) % 2 != 0) {
            printf("NO\n");
        } else {
            ll p = (m - sq) / 2;
            ll q = (m + sq) / 2;
            if (p <= 0 || q <= 0) {
                printf("NO\n");
            } else {
                printf("%lld %lld\n", p, q);
            }
        }
    }
    return 0;
}