中级题:100分
描述:一条长廊里依次装有n(1 ≤ n ≤ 65535)盏电灯,从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。开始,电灯全部关着。
有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。注:电灯数和学生数一致。
输入:电灯的数量
输出:亮着的电灯数量
样例输入:3 ,样例输出:1
解题思路1:这道题,如果要模拟的话,当然是可以的,但对于代码基础较差的同学写起来就比较吃力了,在这里写模拟的做法
解题思路2:在这道题上面多思考思考,可以看出,对于任何一个灯来说,比如12,其因数有1,2,3,4,6,12。说明,编号为1,2,3,4,6,12的学生分别要拉它一下,在这里发现,1*12=12,2*6=12,3*4=12,所以其因数都是一一对应的,也就是,1拉的那一下被12抵消了,2拉的那一下被6抵消了,那么谁不会被抵消呢?答案是平方数,比如9的因数是1,3,9,那么3*3=9,而3只拉一次,所以不会被抵消。因此,这道题的答案就是,输入的n以内的平方数个数,等于(int)sqrt(n)。
从这道题可以看出,编程的很多时候,多思考比多动笔要有用的多。
#include<iostream> using namespace std; void main() { int n; cin>>n; int numLightOn = 0; for(int i=1;(i*i)<=n;i++) numLightOn++; cout<<numLightOn<<endl; }
用模拟的方法代码如下:
#include<iostream> #include<vector> using namespace std; void main() { int n; cin>>n; vector<int> light(n+1,0);//0表示灭的,1表示亮的 int numLightOn=0; for(int i=1;i<=n;i++)//n个人 { int j=i; int times = 2; while(j<=n) { light[j]= 1-light[j]; // 0->1,1->0 j = i; //第j盏灯 j *= times; times++; } }//end for for(int i=1;i<=n;i++) { if(light[i]==1) numLightOn++; } cout<<numLightOn<<endl; }
华为机试(7)
时间: 2024-10-15 01:42:14