题目:
走廊有编号为1~n的n盏灯,以及同样编号的n个人。每个人依次执行以下动作:将编号为 人的编号的整数倍 的灯全部按一次。如编号为1的人会按一次所有的灯,编号为3的人会按一次所有编号为3的倍数的灯...
开始的时候灯全灭,问最后有几盏灯亮着?
思路:用枚举法有点笨拙。首先的想法是:对称性。输入为n,int k=sqrt(n)。k的左边和右边的能整除的整数的数量是一样的。
举例18,开方为4.2左右。4.2左边分别有1,2,3。分别对应右边的18,9,6。因为18/1=18,18/18=1。所以18肯定被按偶数次,结果是灭的。
举例16,开方为4。 4的左边有1,2。右边有16,8.这四个数是对称的。关键在于4本身,因为没有数和它匹配,它孤单了。所以16被按奇数次。16是亮着的。
这个对称性是关于乘积的对称性,而不是求和之类的。
代码:
int times(int n)//判断是不是可开方的附加实例
{
int mid = (int)sqrt((double)n);
if (mid*mid == n)return 1;
else return 0;
}
void main()
{
int in;
cin >> in;
int count = 0;
for (int i = 1;i *i<= in;i++)
count +=1;
cout << count << endl;
}
全部的复杂度为sqrt(in)。