【题解】P8813 题解
2023 年 10 月 15 日更新:增加注释,修改错误的代码。感谢 hexuchen 大佬指出。
2024 年 7 月 31 日更新:没想到两年前写的题解能被这么多人看到,也非常感谢各位的支持!现在评论区中提出了一些问题,这里就这些问题统一回答,并对评论区中有价值的建议对题解进行了修改。
-
Q:方法太复杂了,没必要!
A:是的,我承认自己当时的考场做法确实较为复杂,相比其他人的做法来看,这个做法显得臃肿而多余。但是我还是想说:这也不失为一种方法。学习 OI,接受一种比较复杂的新思路也是重要的,万一后面这种思想可以被用于其它题目呢?
-
Q:判断 是否小于 ,小于 代表溢出。看看它溢不溢出就行了。
A:请注意:带符号整数溢出在 C++ 中是未定义行为,这意味着编译器可以随意地处理这种行为,比如,编译器返回 代表溢出也是可以的,所以这种做法有风险,虽不失为一种方法,但在考场上使用务必谨慎。
-
Q:特判 时需考虑 是否大于1,特判 时需考虑 是否大于 吗?
A:不需要。请注意当 或 等于 时,根据数据范围和 可以肯定答案不会超过 。
P8813 题解
思路分析
这道题主要是特判。
首先我们发现, ,。即 或 时必定大于 。但是注意这是在满足 时才有的结论。所以注意特判 和 , 时直接输出 , 时直接输出 。
但是余下的怎么办呢?显然,当 时,说明 。依此判断即可。由于此时 ,大于 的情况已经被特判掉了,于是直接暴力计算就行。
代码
#include <iostream>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
//特判
if(a == 1)
{
cout << 1 << endl;
return 0;
}
if(b == 1)
{
cout << a << endl;
return 0;
}
if(a > 31622)
{
cout << -1 << endl;
return 0;
}
if(b > 29)
{
cout << -1 << endl;
return 0;
}
long long fac = 1;
for(int i = 1;i <= b;i++) //i 表示准备乘上第 i 个 a
{
if((1e9 / double(fac)) < a) //准备乘上的时候看看是否超出限制
{
cout << -1 << endl;
return 0;
}
fac *= a;
}
cout << fac << endl;
return 0;
}

浙公网安备 33010602011771号