题解不易,手下留赞
文章目录
T1
T2
题面
[CSP-J 2022] 乘方
题目描述
小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 a a a 和 b b b,求 a b a^b ab 的值是多少。
a b a^b ab 即 b b b 个 a a a 相乘的值,例如 2 3 2^3 23 即为 3 3 3 个 2 2 2 相乘,结果为 2 × 2 × 2 = 8 2 \times 2 \times 2 = 8 2×2×2=8。
“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误。
小文很快意识到,她的程序里的变量都是 int 类型的。在大多数机器上,int 类型能表示的最大数为
2
31
−
1
2^{31} - 1
231−1,因此只要计算结果超过这个数,她的程序就会出现错误。
由于小文刚刚学会编程,她担心使用 int 计算会出现问题。因此她希望你在
a
b
a^b
ab 的值超过
10
9
{10}^9
109 时,输出一个 -1 进行警示,否则就输出正确的
a
b
a^b
ab 的值。
然而小文还是不知道怎么实现这份程序,因此她想请你帮忙。
输入格式
输入共一行,两个正整数 a , b a, b a,b。
输出格式
输出共一行,如果
a
b
a^b
ab 的值不超过
10
9
{10}^9
109,则输出
a
b
a^b
ab 的值,否则输出 -1。
样例 #1
样例输入 #1
10 9
样例输出 #1
1000000000
样例 #2
样例输入 #2
23333 66666
样例输出 #2
-1
提示
对于
10
%
10 \%
10% 的数据,保证
b
=
1
b = 1
b=1。
对于
30
%
30 \%
30% 的数据,保证
b
≤
2
b \le 2
b≤2。
对于
60
%
60 \%
60% 的数据,保证
b
≤
30
b \le 30
b≤30,
a
b
≤
10
18
a^b \le {10}^{18}
ab≤1018。
对于
100
%
100 \%
100% 的数据,保证
1
≤
a
,
b
≤
10
9
1 \le a, b \le {10}^9
1≤a,b≤109。
[CSP-J 2022] 解密
题目描述
给定一个正整数 k k k,有 k k k 次询问,每次给定三个正整数 n i , e i , d i n_i, e_i, d_i ni,ei,di,求两个正整数 p i , q i p_i, q_i pi,qi,使 n i = p i × q i n_i = p_i \times q_i ni=pi×qi、 e i × d i = ( p i − 1 ) ( q i − 1 ) + 1 e_i \times d_i = (p_i - 1)(q_i - 1) + 1 ei×di=(pi−1)(qi−1)+1。
输入格式
第一行一个正整数 k k k,表示有 k k k 次询问。
接下来 k k k 行,第 i i i 行三个正整数 n i , d i , e i n_i, d_i, e_i ni,di,ei。
输出格式
输出 k k k 行,每行两个正整数 p i , q i p_i, q_i pi,qi 表示答案。
为使输出统一,你应当保证 p i ≤ q i p_i \leq q_i pi≤qi。
如果无解,请输出 NO。
样例 #1
样例输入 #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
提示
【数据范围】
以下记 m = n − e × d + 2 m = n - e \times d + 2 m=n−e×d+2。
保证对于
100
%
100\%
100% 的数据,
1
≤
k
≤
10
5
1 \leq k \leq {10}^5
1≤k≤105,对于任意的
1
≤
i
≤
k
1 \leq i \leq k
1≤i≤k,
1
≤
n
i
≤
10
18
1 \leq n_i \leq {10}^{18}
1≤ni≤1018,
1
≤
e
i
×
d
i
≤
10
18
1 \leq e_i \times d_i \leq {10}^{18}
1≤ei×di≤1018
,
1
≤
m
≤
10
9
1 \leq m \leq {10}^9
1≤m≤109。
| 测试点编号 | k ≤ k \leq k≤ | n ≤ n \leq n≤ | m ≤ m \leq m≤ | 特殊性质 |
|---|---|---|---|---|
| 1 1 1 | 1 0 3 10^3 103 | 1 0 3 10^3 103 | 1 0 3 10^3 103 | 保证有解 |
| 2 2 2 | 1 0 3 10^3 103 | 1 0 3 10^3 103 | 1 0 3 10^3 103 | 无 |
| 3 3 3 | 1 0 3 10^3 103 | 1 0 9 10^9 109 | 6 × 1 0 4 6\times 10^4 6×104 | 保证有解 |
| 4 4 4 | 1 0 3 10^3 103 | 1 0 9 10^9 109 | 6 × 1 0 4 6\times 10^4 6×104 | 无 |
| 5 5 5 | 1 0 3 10^3 103 | 1 0 9 10^9 109 | 1 0 9 10^9 109 | 保证有解 |
| 6 6 6 | 1 0 3 10^3 103 | 1 0 9 10^9 109 | 1 0 9 10^9 109 | 无 |
| 7 7 7 | 1 0 5 10^5 105 | 1 0 18 10^{18} 1018 | 1 0 9 10^9 109 | 保证若有解则 p = q p=q p=q |
| 8 8 8 | 1 0 5 10^5 105 | 1 0 18 10^{18} 1018 | 1 0 9 10^9 109 | 保证有解 |
| 9 9 9 | 1 0 5 10^5 105 | 1 0 18 10^{18} 1018 | 1 0 9 10^9 109 | 无 |
| 10 10 10 | 1 0 5 10^5 105 | 1 0 18 10^{18} 1018 | 1 0 9 10^9 109 | 无 |
题解
第一题题解
针对第一题,先思考一下。
首先,
a
b
a^b
ab要小于
1
0
9
10^9
109,我们可以先把这个数算出来。
我估计有的小盆友会懵:

我会回答:

强算当然会炸,但题目让你答案小于
1
0
9
10^9
109在输出,这非常符合longlong类型的标准,也就是说,如果要你输出答案那一定不会炸longlong,在垒乘时,我们只需要特判,如果大于1e9,直接判掉。输出“No”,如下伪代码。
ret = 1;
// b和a就是题目里的b和a
for i : 1 to b then
ret *= a;
if ret > 1e9 then
puts("-1");
return 0;
当然,最后只要输出ret就好了.
hint
a = 1 a = 1 a=1时,要特判,否则会当 b = 1 e 9 b = 1e9 b=1e9时,会TLE。
AC代码
// 以前写的代码,特丑。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string s;
signed main(){
int a,b;
cin >> a >> b;
if (a == 1) cout << 1 << endl;
else{
int t = 1;
for (int i = 1 ; i <= b ; i++){
if (t > 1e9) {
t = -1;
break;
}
t *= a;
}
if (t > 1e9) t = -1;
cout << t << endl;
}
return 0;
}
第二题题解
这道题呢,说实话,思维难度是有的,但不是特别大。
其实刚拿到这题时,有点无从下手。但细细一想,会发现并不难。
首先 ,对于每组数据,令
n
=
p
i
q
i
,
p
=
p
i
,
q
=
q
i
,
e
=
e
i
,
d
=
d
i
n = p_iq_i , p = p_i,q = q_i , e = e_i,d = d_i
n=piqi,p=pi,q=qi,e=ei,d=di
这里, p i q i = p i × q i p_iq_i = p_i \times q_i piqi=pi×qi ,下文也是这样。
由题意得: { n = p q e d = ( p − 1 ) ( q − 1 ) + 1 \begin{cases} n = pq \\ ed = (p - 1)(q - 1) + 1 \end{cases} {n=pqed=(p−1)(q−1)+1
计算二式,得:
e
d
=
p
q
−
p
−
q
+
1
+
1
=
p
q
−
p
+
2
ed = pq - p - q + 1 + 1 = pq - p + 2
ed=pq−p−q+1+1=pq−p+2
又
∵
n
=
p
q
又\because n = pq
又∵n=pq
∴
e
d
=
n
−
p
−
q
+
2
\therefore ed = n - p - q + 2
∴ed=n−p−q+2
∴
移项
,
得:
e
d
+
(
p
+
q
)
=
n
+
2
\therefore 移项,得: ed + (p + q) = n + 2
∴移项,得:ed+(p+q)=n+2
∴
p
+
q
=
n
−
e
d
+
2
\therefore p + q = n - ed + 2
∴p+q=n−ed+2
令 m = n - ed + 2,
首先我们来学习(温习)一下,初一学过的知识(完全平方公式)。
(
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
=
(
a
2
+
2
a
b
+
b
2
)
−
(
a
2
−
2
a
b
+
b
2
)
=
4
a
b
\therefore (a + b) ^ 2 - (a - b) ^ 2 = (a^2 + 2ab + b^2) - (a^2 - 2ab + b^2) = 4ab
∴(a+b)2−(a−b)2=(a2+2ab+b2)−(a2−2ab+b2)=4ab
∴
p
−
q
=
(
p
+
q
)
2
−
4
p
q
\therefore p - q = \sqrt{(p + q)^2 - 4pq}
∴p−q=(p+q)2−4pq
连立两式,得:
{
p
+
q
=
n
−
e
d
+
2
=
m
p
−
q
=
(
p
+
q
)
2
−
4
p
q
\begin{cases} p + q = n - ed + 2 = m \\ p - q = \sqrt{(p + q)^2 - 4pq} \end{cases}
{p+q=n−ed+2=mp−q=(p+q)2−4pq
用m和n替换一下:
{ p + q = m p − q = m 2 − 4 n \begin{cases} p + q = m \\ p - q = \sqrt{m^2 - 4n} \end{cases} {p+q=mp−q=m2−4n
又是一个小学的知识:和差问题,不会的某度自学。
{
值大的式子 + 值小的式子 = 大的数的两倍
值大的式子
−
值小的式子
=
小的数的两倍
\begin{cases} \text{值大的式子 + 值小的式子 = 大的数的两倍} \\ {值大的式子 - 值小的式子 = 小的数的两倍} \end{cases}
{值大的式子 + 值小的式子 = 大的数的两倍值大的式子−值小的式子=小的数的两倍
举个例子
如上面:
{
p
+
q
=
m
p
−
q
=
m
2
−
4
n
\begin{cases} p + q = m \\ p - q = \sqrt{m^2 - 4n} \end{cases}
{p+q=mp−q=m2−4n
用一式去加二式,得:
2
p
=
m
+
m
2
−
4
n
2p = m + \sqrt{m^2 - 4n}
2p=m+m2−4n
用一式去减二式,得:
2
q
=
m
−
m
2
−
4
n
2q = m - \sqrt{m^2 - 4n}
2q=m−m2−4n
∴
{
p
=
m
+
m
2
−
4
n
2
q
=
m
−
m
2
−
4
n
2
\huge \therefore \begin{cases} p = \frac{m + \sqrt{m^2-4n}}{2} \\ q = \frac{m - \sqrt{m^2-4n}}{2}\end{cases}
∴⎩
⎨
⎧p=2m+m2−4nq=2m−m2−4n
AC代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define all(s) s.begin(),s.end()
#define endl "\n"
const int N = 5e5 + 5;
const int M = 1005;
signed main() {
int T;
scanf("%d",&T);
while (T --) {
ll n , e , d;
scanf("%lld %lld %lld" , &n , &d , &e);
ll m = n - e * d + 2;
if (1ll * m * m < 4ll * n) {
printf("NO\n");
continue;
}
ll ret = sqrt(m * m - 4ll * n);
if (ret * ret != m * m - 4ll * n) {
printf("NO\n");
continue;
}
ll p = (m + ret) / 2 , q = (m - ret) / 2;
printf("%lld %lld\n" , q , p);
}
}
hint
当
m
2
<
4
n
或
m
2
−
4
n
m^2 < 4n 或 m^2-4n
m2<4n或m2−4n不是一个完全平方数的时候,没有正整数解,也就是题目中的“NO”
还有,题目输出,先输出q,再输出p
T
h
e
e
n
d
.
\huge The \space end.
The end.
文章提供了两道CSP-J2022竞赛的题目解析。第一题要求计算不超过10^9的a^b值,若超出则输出-1。第二题涉及数学和逻辑,要求找到满足特定条件的正整数对(p_i,q_i),并处理无解情况。文章给出了解题思路和提示。
625

被折叠的 条评论
为什么被折叠?



