开灯问题(数学思路)
是的,你没有看错,就是简单的开灯问题,难度仅为入门,但是这题在做的时候我也仅是找到了规律,并没有证明出来时为什么,直到看大犇的证明,我才发现,我在数学上真的还是太拉了,话不多说还请看题
题目传送门——开灯问题
题意:就是说给你n个灯,n轮游戏,到了第 i 轮 ,所有因数有 i 的都要进行一次操作(换言之,i 的倍数都要进行一次操作),然后问你哪些灯是开的,哪些灯是关的
思路:刚读题的时候,我认为这不模拟一下就过了,直到我看到了数据为2^40,我才认为这题是有规律的,一开始我是自己在纸上画到了9,然后发现了完全平方数的规律,然后才做出来的
But,我们可以写出一种数学的证明
(1)首先来分析什么情况下灯是开的:一开始灯的状态是关的,但是最后要是开的,说明对灯进行了奇数次操作
(2)再来分析什么时候才会对灯进行操作: 只有轮次 i 为灯 k 的因数的时候,即 k%i==0,才能对灯进行操作
(3)哪些数才会有奇数个因子:首先我们设 p 为质数, a 为指数。
由分解质因数可知:对于任意任意的合数,都可以分解成若干个质数相乘的形式
可以记为 n^2=p1^a1+p2^a2+……+pk^ak;
然后对于任意的正整数,计算因数个数的公式为:(a1+1)*(a2+1)*……*(ak+1) (这里的a指的是质数的指数)
计算因数个数的公式的推导:
我们知道1为所有数的因数,而我们的每一项质数都有a的指数,那么我们可以说我们对1乘以每个质数的范围内的指数(0~a)都是这个数的因数,所以对于第一项质数,我们可以乘的次数就是a1+1,然后一次类推,最后因数个数的公式为(a1+1)*(a2+1)*……*(ak+1
那么也就是说只有上面每一项都为奇数,最终的因子才能为奇数,也就是说每一个指数a都是偶数
结合分解质因数公式,假设n能拆分成若干个质数,那么n^2得到的质数的指数一定为偶数,所以只有完全平方数才能够,满足条件,因数的个数为奇数
然后就是朴实无华的小代码:
#include<bits/stdc++.h>
using namespace std;
#define int long longint n;
signed main()
{cin>>n;for(int i=1;i*i<=n;i++){cout<<i*i<<" ";}return 0;
}