2、机场指示灯--赛码网周考(0609)
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
机械工小王在一次乘坐飞机时对机场的跑道指示灯比较感兴趣,他想设计一种模拟电路控制机场指示灯的亮灭以便在紧急情况中可以用指示灯的排列来向机场人员传达某种信号。
小王在模拟电路中设计了 n 个指示灯,每个指示灯操作一次就会将其状态改变,即:点亮转为关闭,或关闭转为点亮。将这些指示灯从 1 到 n 编号,开始的时候所有指示灯都是关闭的。小王计划在模拟电路中上执行如下动作:将编号为2的倍数的所有指示灯操作一次,也就是把 2 4 6 8 ... 等序号指示灯点亮。将编号为3的倍数的所有指示灯操作一次, 也就是对 3 6 9 ... 等序号指示灯操作,注意此时6 12 18 ... 等序号指示灯又关闭了。将编号为4的倍数的所有指示灯操作一次。
输入
3个用空格分开的正整数分别为:N L R (L<R<N<10^15) N表示指示灯数,L表示区间的左边界,R表示区间的右边界。
输出
输出1个整数,表示经过所有操作后,[L,R] 区间中有多少个指示灯是点亮的。
样例输入
5 2 3
样例输出
2
解题思路:本题太坑了,读题的时候以为只做2 3 4的倍数,实际题目是到n的倍数都操作一遍
用0表示等处于关闭状态。然后针对每一个灯(区间内),如果是2-n的倍数就转变状态。最后输出状态为1的数目
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define maxn 100005 5 typedef long long ll; 6 ll a[maxn]; 7 int main() 8 { 9 ll n,l,r; 10 while(cin>>n>>l>>r) 11 { 12 for(int i=l;i<=r;i++) 13 a[i]=0; 14 15 for(int i=l;i<=r;i++) 16 { 17 for(int j=2;j<=n;j++) 18 { 19 if(i%j==0) 20 a[i]^=1; 21 } 22 } 23 int res=0; 24 for(int i=l;i<=r;i++) 25 { 26 if(a[i]) 27 res++; 28 } 29 cout<<res<<endl; 30 31 } 32 return 0; 33 }
解题思路二:针对每一个数,除了完全平方数都是偶数个数乘积的结果。例如 6 = 2*3 = 1* 6 gong 4个数。因为1的倍数是不操作的,所以针对非完全平方式6,操作其2-n的倍数,其实就操作了奇数次,即2 3 6 的倍数时操作。因此状态与起始相反。对于完全平方数例如4,操作了2 4偶数次,因此和原始状态相同。所以即计算l-r区间内非完全平方数的个数即可。因此计算出完全平方数个数ans。非完全平方数个数为r-l+1-ans
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <algorithm> 5 6 int main() 7 { 8 using namespace std; 9 long long n, l, r; 10 while (cin >> n >> l >> r) { 11 int temp = sqrt((double)l); 12 long long i = temp * temp; 13 long long ans = -1; 14 if (i == l) { 15 ans++; 16 } 17 while (i <= r) { 18 ans++; 19 temp++; 20 i = temp * temp; 21 } 22 cout << r - l + 1 - ans << endl; 23 } 24 return 0; 25 }