P8814 [CSP-J 2022] 解密

题目描述

传送门

给定一个正整数 k,有 k 次询问,每次给定三个正整数 ni,ei,di,求两个正整数 pi,qi,使 ni=pi×qiei×di=(pi1)(qi1)+1

输入格式

第一行一个正整数 k,表示有 k 次询问。

接下来 k 行,第 i 行三个正整数 ni,di,ei

输出格式

输出 k 行,每行两个正整数 pi,qi 表示答案。

为使输出统一,你应当保证 piqi

如果无解,请输出 NO

样例

样例输入

10
770 77 5
633 1 211
545 1 499
683 3 227
858 3 257
723 37 13
572 26 11
867 17 17
829 3 263
528 4 109

样例输出

2 385
NO
NO
NO
11 78
3 241
2 286
NO
NO
6 88

思路

数据范围

测试点编号 k n m 特殊性质
1 103 103 103 保证有解
2 103 103 103
3 103 109 6×104 保证有解
4 103 109 6×104
5 103 109 109 保证有解
6 103 109 109
7 105 1018 109 保证若有解则 p=q
8 105 1018 109 保证有解
9 105 1018 109
10 105 1018 109

由数据范围可知,要开long long.

由题目给出的代数式手动解,你会看到惊喜:

p+q=ned+2

在题目的数据范围标题下,你会看见:

m=ne×d+2

这恰好说明,我们手动解代数式的思路是对的。

初一学生看到这里应该会异常兴奋,因为在初一就学过了一元二次方程,其中告诉我们要解出p,q的值,就要算出p+qpq的值。而我们现在已知p+q=ned+2,pq=n,通过完全平方公式,就可以得到pq了。

解题过程略(真的太长了)。

综上所述,我们可以解出:

p=(m+sqrt(m2+4n))/2

q=(msqrt(m2+4n))/2

其中,m=ned+2.

但是,为了防止喜提WA,我们还需要进行特判。

这道题只要掌握了思路,代码还是很好写的。

代码实现

#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
long long n,e,d;
cin>>n>>e>>d;
long long m=n-e*d+2;
long long p,q;
p=(m+sqrt(m*m-4*n))/2;
q=(m-sqrt(m*m-4*n))/2;
if(n==p*q&&e*d==p*q-q-p+2&&p!=0&&q!=0){
cout<<min(p,q)<<" "<<max(p,q)<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
posted @   j1hx  阅读(247)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示