leetcod319.灯泡开关

题目大意

初始时有 n 个灯泡关闭。 第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。 找出 n 轮后有多少个亮着的灯泡。

示例:

输入: 3
输出: 1 
解释: 
初始时, 灯泡状态 [关闭, 关闭, 关闭].
第一轮后, 灯泡状态 [开启, 开启, 开启].
第二轮后, 灯泡状态 [开启, 关闭, 开启].
第三轮后, 灯泡状态 [开启, 关闭, 关闭]. 

解题思路

所有灯泡初始时刻都是关闭状态,第i轮时,每i个灯泡转换一次状态。因此对于灯泡k来说,在整个过程中转换状态的次数是k的因子的数量。例如:k=6,因子有1,2,3,6.则第一轮、第二轮、第三轮和第六轮都会转换状态。
有了这个思路之后就很简单了,我们求得1~n中,每个数字的因子数量,如果是奇数则表明最后灯泡开启,偶数表明灯泡关闭。

class Solution {
public:
    int bulbSwitch(int n) {
    	if (n < 2)
    		return n;

    	int res = 0;
    	for (int i = 1; i < n; ++i){
    		int sq = sqrt(i);
    		int count = 2;
    		for (int j = 2; j <= sq; ++j){
    			if (i % j == 0)
    				count += 2;
    		}
    		if (sq * sq == i)
    			--count;

    		if(count % 2 == 1)
    			++res;
    	}
    	return res;
    }
};

上述方法运行超时。分析代码可知,只有当数字k的因子数量是奇数时灯泡最后才会开启。而由上面代码的条件可知,只有当k的完全平方数的时候因子数量才是奇数。(例如9,1 *9, 3 *3,只要有一个较小的因子,毕竟有一个较大的因子对应,所以因子数量是偶数。但是如果是完全平方数,则这两个因子相同,只记为1个。)
所以题目变成了求1~n中有多少个完全平方数。

class Solution {
public:
    int bulbSwitch(int n) {
    	return int(sqrt(n));
    }
};

猜你喜欢

转载自blog.csdn.net/qq_41092190/article/details/106069117