CSP-J 2022复赛T2 解密--分析

本文解决了2022年的csp-j复赛中解密(T2)这道题。

第一篇文章的分析:
CSP-J 2022复赛T1 乘方--分析_jinjiayang的博客-CSDN博客

题面

题目描述

给定一个正整数 kk,有 kk 次询问,每次给定三个正整数 ni​,ei​,di​,求两个正整数 pi​,qi​,使 ni​=pi​×qi​、ei​×di​=(pi​−1)(qi​−1)+1。

输入格式

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

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

输出格式

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

为使输出统一,你应当保证 pi​≤qi​。

如果无解,请输出 NO

输入输出样例

输入 #1

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

输出 #1

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

数学公式

(a+b)^2 = a^2 + b^2 + 2ab
(a-b)^2 = a^2 + b^2 - 2ab
(a+b)^2 - (a-b)^2 = 4ab
(a-1)(b-1) = ab-a-b+1

分析 

对这种题来说,我们第一件事就是解数学方程式

n = pq
ed = (p-1)(q-1) + 1
ed = pq-p-q+2
p+q = n-ed+2 = m

这就是我们现在化简后的方程,已知两个数的和与两个数的积,求两个数

下面开始解方程

pq = n
p+q = m
  (p-q)^2
= p^2+q^2-2pq
= (p+q)^2-4pq
= m^2-4n
p-q = √m^2-4n
p+q = m
2p = (√m^2-4n) + m
p = [(√m^2-4n) + m]/2
q = m-p

 或

pq = n
p+q = m
p(m-p) = n
q(m-q) = n

pm - p^2 = n
- p^2 + pm - n = 0
p = -m±(√m^2-4n) / -2
p = (√m^2-4n)+m / 2
q = m-p

即一元二次方程求解:

p+q=-b/a

pq=c/a

一元二次方程求根公式扩展资料

一元二次方程都可化为ax^2+bx+c=0,它的解是:

p = {[√(n-ed+2)^2-4n] + (n-ed+2)}
q = (n-ed+2) - p

若根号下的数据有整数解,则有整数解

代码

 即可得出代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int k, n, e, d, p, q, a, b;

signed main()
{
	ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
	cin >> k;
	while(k--)
    {
		cin >> n >> e >> d;
        a = n + 2 - e * d; 
		b = sqrt(a * a - 4 * n); 
		p = (a + b) / 2;
		q = a - p;
		if(p * q == n)
        {
			if(p > q) swap(p, q);
			cout << p << " " << q << endl;
		}
		else cout << "NO" << endl;
	}
	return 0;
}

这可以通过O(k)的复杂度来求解问题。

对了,除此以外还有通过二分的方法来实现,就不具体展开了

//@lyoi20210204
//感谢他的代码!
#include <bits/stdc++.h>
using namespace std;
 
int main(){
	long long x,y,z,m,k;
	cin>>k;
	for(int i=1;i<=k;++i){
		cin>>x>>y>>z;
		m=x-y*z+2;
		long long l=0,r=m/2+1;
		while(l+1<r){
			long long mid=(l+r)/2;
			if(mid*(m-mid)<=x){
				l=mid;
			}else{
				r=mid;
			}
		}
		if(l*(m-l)==x){
			cout<< l << " " << x/l << endl;
		}else{
			cout<< "NO" << endl;
		}
	}
	return 0;
}

Time to 点赞

看完后,别忘了

点赞!

收藏!

Thanks……

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嘉定世外的JinJiayang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值