FakeNews - 题解
标签与难度
标签: 数学, 数论, 规律题, O(1)
难度: 1200
题目大意喵~
你好呀,未来的算法大师!我是你们的我小助教,喵~ 让我们一起来看看这道有趣的题目吧!
题目是这样的:有一个自称很懂数学的大人物宣称,从1到n的平方和(也就是 )永远不可能是另一个整数的平方。我们要做的就是当一名“记者”,戳穿他的“Fake news!”。
简单来说,就是给我们一个正整数 ,我们需要判断 是否是一个完全平方数。
- 输入: 会有多组测试数据。每组数据给出一个整数 。
- 输出: 如果那个和是完全平方数,我们就输出 "Fake news!",表示大人物说错了。如果不是,我们就输出 "Nobody knows it better than me!",表示他这次说对了。
举个栗子🌰:
- 如果 , 那么和就是 , 而 是 ,所以是完全平方数。
- 如果 , 和是 , 这可不是任何整数的平方哦。
解题思路分析
喵~ 这个问题看起来很数学,但别担心,跟着我的猫爪印一步步来,你会发现它其实很可爱!
第一步:把问题变简单!
首先,我们要计算那个长长的和:。每次都用循环去加肯定太慢啦,幸好聪明的数学家们早就为我们准备好了公式,的说!
平方和公式:
有了这个公式,问题就变成了:判断 是不是一个完全平方数。
第二步:最直接的想法——暴力计算!
最直观的思路就是,对于每个给定的 ,我们直接套用公式计算出这个和 sum,然后判断 sum 是不是完全平方数。
怎么判断一个数 sum 是不是完全平方数呢? 一个简单的方法是:
- 计算
sum的平方根,long long root = sqrt(sum)。这里sqrt函数会返回一个浮点数,我们把它强制转换成整数,会去掉小数部分。 - 然后我们检查
root * root是否等于sum。如果相等,那sum就是一个完美的完全平方数啦!
这个方法在大多数情况下都是可行的,就像参考代码1那样。但是,作为一个追求极致的我,我总觉得还有更优雅的解法,喵~
第三步:寻找隐藏的规律!
让我们来当一回侦探,测试一下前面几个 的值,看看能不能发现什么线索,呐?
- n = 1: 和 = 。是完全平方数! (Fake news!)
- n = 2: 和 = 。不是。
- n = 3: 和 = 。不是。
- n = 4: 和 = 。不是。
- ... (我们继续往下找) ...
- ... (找呀找呀找朋友) ...
- n = 24: 和 = 。是完全平方数! (Fake news!)
我们发现了两个让大人物被打脸的例子: 和 。
这时候,一个大胆的猜想就浮现在了我的猫猫脑海里:会不会...只有这两个解呢?
第四步:揭开谜底!
这个猜想是正确的!这个问题在数学上被称为**“炮弹问题” (Cannonball Problem)**,因为它等价于问:需要多少个炮弹才能堆成一个正四角锥,并且这些炮弹又能恰好在地面上摆成一个正方形?
这是一个著名的数论问题,数学家们在很久以前就已经证明,除了平凡解 之外,只有当 和 时,这个平方和才是一个完全平方数。
这个证明过程涉及到了椭圆曲线,对于我们算法竞赛来说有点太复杂了,喵~ 但我们可以心安理得地使用这个结论!
所以,这道题的最终解法就是: 判断输入的 n 是否等于 1 或者 24。
- 如果是,就输出 "Fake news!"。
- 如果不是,就输出 "Nobody knows it better than me!"。
这样一来,问题就变成了一个超级简单的判断题,时间复杂度瞬间降到了 ,是不是超级厉害!这就是数学的魅力呀,喵~
代码实现
下面就是我根据这个绝妙的思路,为你精心准备的代码啦!注释里有我的小心思哦~
#include <iostream>
// 使用快速 I/O,让我们的程序跑得像猫一样快,喵~
void fast_io() {
// 关闭 C++ 标准流与 C 标准流的同步
std::ios_base::sync_with_stdio(false);
// 解除 cin 和 cout 的绑定
std::cin.tie(NULL);
}
// 解决单个测试用例的函数
void solve() {
long long n;
std::cin >> n;
// 根据我们发现的数学规律(炮弹问题)
// 只有当 n=1 或 n=24 时, 1到n的平方和才是一个完全平方数
if (n == 1 || n == 24) {
std::cout << "Fake news!\n";
} else {
std::cout << "Nobody knows it better than me!\n";
}
}
int main() {
fast_io();
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}复杂度分析
时间复杂度: 对于每个测试用例,我们只进行了一次简单的
if-else判断,这个操作是常数时间 的。如果有 个测试用例,总时间复杂度就是 ,超级快!空间复杂度: 我们没有使用任何随输入规模 变化的额外存储空间,只用了几个变量。所以空间复杂度是 ,非常节省内存的说。
知识点总结
通过这道题,我们学到了不少好东西呢,喵~
平方和公式: 这是一个非常基础且重要的求和公式,要记在小本本上哦!
完全平方数判断: 虽然我们最后没用上,但
long long root = sqrt(x); if (root * root == x)是判断一个数是否为完全平方数的常用技巧。竞赛中的规律探索: 面对看似复杂的计算题,先别急着硬算。可以尝试计算一些小数据,观察其结果,往往能发现意想不到的简单规律。这是一种非常重要的解题策略!
炮弹问题 (Cannonball Problem): 作为一个有趣的知识点,知道了这个问题的背景,不仅能让我们秒解此题,还能在小伙伴面前小秀一下知识储备,是不是很酷?
好啦,这次的题解就到这里啦!希望对你有帮助,喵~ 继续加油,你一定能成为最棒的算法大师!