【寒假每日一题】AcWing 4729. 解密(补)

这篇文章讨论了一个编程挑战,即解密问题,它涉及到寻找满足特定数学关系的正整数对。通过应用韦达定理及其逆定理,可以将问题转化为求解一元二次方程。文章提供了解题思路、时间复杂度分析以及代码实现,展示了解决此类问题的方法。然而,对于某些输入,可能存在无解的情况,此时输出为NO。
摘要由CSDN通过智能技术生成

一、题目

1、原题链接

4729. 解密

2、题目描述

给定一个正整数 k,有 k次询问,每次给定三个正整数 ni,ei,di,求两个正整数 pi,qi,使 n i = p i × q i ni=pi×qi ni=pi×qi e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 ei×di=(pi−1)(qi−1)+1 ei×di=(pi1)(qi1)+1
输入格式
第一行一个正整数 k,表示有 k次询问。
接下来 k行,第 i 行三个正整数 ni,di,ei。
输出格式
输出 k
行,每行两个正整数 pi,qi
表示答案。
为使输出统一,你应当 保证 pi≤qi
如果无解,请输出 NO
数据范围
以下记 m=n−e×d+2
保证对于 100% 的数据,1≤k≤105,对于任意的 1≤i≤k1≤ni≤10181≤ei×di≤10181≤m≤109

输入样例

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

二、解题报告

思路来源AcWing 4729. 解密(寒假每日一题2023)
y总yyds

1、思路分析

1)通过题目 n i = p i × q i ni=pi×qi ni=pi×qi e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 ei×di=(pi−1)(qi−1)+1 ei×di=(pi1)(qi1)+1,两个公式化简可以推出 p i + q i = n − e i ∗ d i + 2 pi+qi=n-ei*di + 2 pi+qi=neidi+2,而题目给出了 m = n − e × d + 2 m=n−e×d+2 m=ne×d+2。所以我们可以有 m = p i + q i m=pi+qi m=pi+qi,通过高亮表示的两式不难联想到韦达定理及其逆定理,我们可以根据上述两式来构造一个一元二次方程,二元方程的解就是对应的piqi
2)模拟上述过程,输出相应结果,即为所求。

2、时间复杂度

时间复杂度为O(n)

3、代码详解

#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=100010;
LL n[N],e[N],d[N],p,q;
int main()
{   int k;
    cin>>k;
    for(int i=0;i<k;i++){
    	cin>>n[i]>>e[i]>>d[i];
	}
	for(int i=0;i<k;i++){
		LL m=n[i]-e[i]*d[i]+2;
		LL d=m*m-4*n[i];
		LL gd=sqrt(d); 
		//判别式大于等于0才有解 
		if(d>=0){
		   //判断解是否为整数
		   /*首先,根号△得为整数,其次最终结果得为整数,
		     分子为偶数才能确保最终结果为整数,此处注意
			 运算符的优先级!高于算术运算符。根据两个分
			 子奇偶性相同,也可简化代码*/ 
		   if(gd*gd==d&&!((m-gd)%2)&&!((m+gd)%2))
			 cout<<(m-gd)/2<<" "<<(m+gd)/2<<endl;
		   else{
		   	  cout<<"NO"<<endl; 
		   }
		} 
		else{
			cout<<"NO"<<endl; 
		}
	}
    return 0;
}

三、知识风暴

韦达定理及其逆定理

韦达定理
针对一个一元二次方程 a2x+bx+c=0,a不为0,且a,b,c均为实数,且存在根,则有 x1+x2=-b/a, x1*x2=c/a
逆定理
如果存在 x1+x2=-b/a, x1*x2=c/a,可据此构造一个一元二次方程使得该方程的解为 x1,x2

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马看到什么是人决定的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值