有100个灯(编号1-100,初始状态全部关闭),现要进行1000轮switch操作(如果原来是关则打开,如果原来开则关闭)。
在第X轮操作中,若灯的编号i能够整除X,则进行switch操作。
那么这1000轮操作结束后,开着的灯是那些呢?
按题意的代码:
void func1()
{
bool light[101]={0};
for(int i = 1; i <= 1000; i++)//x loop
{
for(int j = 1; j < 101; j++)//light
if(j%i == 0)
light[j] = light[j]==true?false:true;
}
for(int i = 1; i< 101; i++)
if(light[i])cout<<i<<endl;
}
稍微优化下:
void func2()
{
bool light[101]={0};
for(int i = 1; i <= 100; i++)//x loop
{
for(int j = i; j < 101; j+=i)//light
light[j] = light[j]==true?false:true;
}
for(int i = 1; i< 101; i++)
if(light[i])cout<<i<<endl;
}
也就这样了吧,还能优化么?
来看看结果:
1
4
9
16
25
36
49
64
81
100
怎么都是平方数?
因为平方数的约数个数为奇数,所以状态发生改变 ;其它数的约数为偶数,状态不变。
为什么?
充分性
1.n=1时正约数1个,是奇数
2.n>1时
n^2的约数:1...n...n^2
1和n之间每多一个约数,例如m,那么n到n^2之间就会多一个约数n^2/m
就是说除了这三个约数,其他的约数是成对出现的,也就是说约数的个数
是3+偶数,结果必为奇数
必要性:
1.如果一个数的公约数是1和他本身,那它就是质数,肯定不是完全平方数
2.如果一个数m的公约数是1和他本身m,还有其他的公约数,我们设其中一个数为p,那么必定存在一个约数m/p
也就是说公约数是成对出现的,除非这两个数相等,也就是同一个数,否则公约数的个数就肯定是偶数
void funcs()
{
for(int i = 1; i <= 100 && i*i <= 100; i++)
cout<<i*i<<endl;
}