开灯问题(赋上详细思路)

版权声明:@ly https://blog.csdn.net/lytwy123/article/details/83042994

    有n盏灯,编号为1-n,第一个人把所有灯打开,第二个人按下所有编号两倍的开关(这些灯被关掉),第三个人按下所有编号三倍的开关,以此类推,一共有k个人,问最后有哪些灯开着?

输入:n和k,输出开着的灯的编号,k<=n<=1000

样例输入:

7 3 

样例输出:

1 5 6 7

算法思路:

其实我们可以采用数组存储多少盏灯的状态,然后模拟接下来的人开关灯的操作,怎么模拟?比如我们设置两个循环,第一个循环是操作的人,第二个循环是对所有的灯循环,通过第二个循环中我们拿每一盏灯的序号来和第几个人操作的来进行取余运算,如果为0,则模拟开关灯操作,就是将数组的值取相反值即可。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int num[1001];      //定义一个数组,保存灯的状态0为关闭,1为打开

int main()
{
	memset(num,0,sizeof(num));   //给数组初始化全部为0
	int n,k;
	cout<<"请输入多少盏灯"<<endl;  //这个在oj上测试删掉即可 
	cin>>n;
	cout<<"请输入多少个人"<<endl;
	cin>>k;
	int flag = 1;   //这个flag标识变量是用来判断输出是否为第一个 ,节省多出来的空格 
	
	for(int i = 1;i<=k;i++){  			// 这两个循环是模拟开关灯操作 
		for(int j = 1;j<=n;j++){		//第一个循环是代表开关灯的倍数,第二个循环是判断开关灯状态以及修改操作 
			if(j%i == 0) num[j] = !num[j];
		}
	} 
	
	for(int i = 1;i<=100;i++){
	if(num[i]){
		if(flag) flag = 0;    //这个是判断输出是否为第一个,是一个输出的技巧避免多出一个空格 
		else cout<<" ";
		cout<<i; 
	} 	
	}
	cout<<endl;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/lytwy123/article/details/83042994