CSP-J 2022 T1乘方 T2解密

文章目录

    • [[CSP-J 2022] T1 - 乘方](#[CSP-J 2022] T1 - 乘方)
    • [[CSP-J 2022] T2 - 解密](#[CSP-J 2022] T2 - 解密)

[CSP-J 2022] T1 - 乘方

将 a a a乘 b b b次,如果这个结果大于 1 e 9 1e9 1e9就输出 − 1 -1 −1,否则输出其结果。

直接循环做乘法,当此时的结果大于 1 e 9 1e9 1e9时可以退出并输出 − 1 -1 −1。

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char const *argv[]) {
	long long a, b, ans = 1;
	cin >> a >> b;
	while (b--) {
		ans *= a;
		if (ans > 1e9) {
			cout << -1 << endl;
			return 0;
		}
	}
	cout << ans << endl;
}

主要是对这个程序复杂度的分析:

  • 当 a a a和 b b b都很大时, a n s ans ans很快就会 > 1 e 9 >1e9 >1e9并退出;
  • 当 a a a很大 b b b很小时,循环要么由于 b = 0 b=0 b=0结束,要么由于 a n s > 1 e 9 ans>1e9 ans>1e9而退出;
  • 当 a a a很小 b b b很大时,最坏的情况是 a = 1 a=1 a=1, b = 1 e 9 b=1e9 b=1e9,此时程序会执行 1 e 9 1e9 1e9次;若 a = 2 a=2 a=2,则程序只会执行 l o g 2 1 e 9 = 30 log_21e9=30 log21e9=30次,所以可以特判一下 a = 1 a=1 a=1的情况。

[CSP-J 2022] T2 - 解密

n i = p i q i n_i=p_iq_i ni=piqi, e i d i = ( p i − 1 ) ( q i − 1 ) + 1 e_id_i=(p_i-1)(q_i-1)+1 eidi=(pi−1)(qi−1)+1
e i d i = p i q i − p i − q i + 2 e_id_i=p_iq_i-p_i-q_i+2 eidi=piqi−pi−qi+2
e i d i = n i − p i − q i + 2 e_id_i=n_i-p_i-q_i+2 eidi=ni−pi−qi+2
p i + q i = n i − e i d i + 2 p_i+q_i=n_i-e_id_i+2 pi+qi=ni−eidi+2

所以有:
{ p i + q i = n i − e i d i + 2 p i q i = n \left\{ \begin{aligned} p_i+q_i&=n_i-e_id_i+2 \\ p_iq_i & = n \end{aligned} \right. {pi+qipiqi=ni−eidi+2=n

完全平方公式 ( a + b ) 2 = a 2 + 2 a b + b 2 (a+b)^2=a^2+2ab+b^2 (a+b)2=a2+2ab+b2, ( a − b ) 2 = a 2 − 2 a b + b 2 (a-b)^2=a^2-2ab+b^2 (a−b)2=a2−2ab+b2。
( a − b ) 2 = ( a + b ) 2 − 4 a b (a-b)^2=(a+b)^2-4ab (a−b)2=(a+b)2−4ab, a − b = ( a + b ) 2 − 4 a b a-b=\sqrt{(a+b)^2-4ab} a−b=(a+b)2−4ab 。

代入得 p i − q i = ( n i − e i d i + 2 ) 2 − 4 n p_i-q_i=\sqrt{(n_i-e_id_i+2)^2-4n} pi−qi=(ni−eidi+2)2−4n 。

与上式相加得 2 p i = n i − e i d i + 2 + ( n i − e i d i + 2 ) 2 − 4 n 2p_i=n_i-e_id_i+2+\sqrt{(n_i-e_id_i+2)^2-4n} 2pi=ni−eidi+2+(ni−eidi+2)2−4n , p i = n i − e i d i + 2 + ( n i − e i d i + 2 ) 2 − 4 n 2 p_i=\frac{n_i-e_id_i+2+\sqrt{(n_i-e_id_i+2)^2-4n}}{2} pi=2ni−eidi+2+(ni−eidi+2)2−4n 。

同理 q i = n i − e i d i + 2 − ( n i − e i d i + 2 ) 2 − 4 n 2 q_i=\frac{n_i-e_id_i+2-\sqrt{(n_i-e_id_i+2)^2-4n}}{2} qi=2ni−eidi+2−(ni−eidi+2)2−4n 。

由于最后的 p i p_i pi和 q i q_i qi要是正整数,所以需要判断一下 d e l t a delta delta。

cpp 复制代码
/*
* @Author: lyle
* @Date:   2024-09-29 14:44:58
* @Last Modified by:   lyle
* @Last Modified time: 2024-09-29 14:44:58
*/

#include <bits/stdc++.h>
#define ll long long

using namespace std;
int k; ll n, d, e;

int main(int argc, char const *argv[]) {
	cin >> k;
	while (k--) {
		cin >> n >> d >> e;
		ll x = n - e * d + 2;
		ll delta = x * x - 4 * n;
		if (delta < 0 or sqrt(delta) * sqrt(delta) != delta) {
			puts("NO");
			continue;
		}
		ll p = (x + sqrt(delta)) / 2;
		ll q = (x - sqrt(delta)) / 2;
		if (q <= 0) {
			puts("NO");
			continue;
		}
		if (p * q != n or e * d != (p - 1) * (q - 1) + 1) {
			puts("NO");
			continue;
		}
		printf("%lld %lld\n", min(p, q), max(p, q));
	}
}
相关推荐
IT德1 小时前
数组增删改查操作
数据结构·算法
NuyoahC1 小时前
算法笔记(五)——分治
c++·笔记·分治
加油,旭杏1 小时前
【Linux】命令管道
linux·服务器·c++·命令管道·mkfifo·unlink
文sir.2 小时前
【leetcode】 45.跳跃游戏 ||
c语言·算法·leetcode
转调2 小时前
每日一练:零钱兑换
开发语言·c++·leetcode
bobostudio19952 小时前
TypeScript 算法手册【快速排序】
前端·javascript·算法·typescript
小小工匠2 小时前
加密与安全_TOTP 一次性密码生成算法
算法·安全·totp
yttandb3 小时前
《重生到现代之从零开始的C语言生活》—— 内存函数
c语言·算法·生活
无夜_3 小时前
c++11新特性
c++
EQUINOX13 小时前
思维+贪心,CF 1210B - Marcin and Training Camp
算法·数学建模·动态规划