首页 > 编程 > C++ > 正文

开灯问题 c++

2019-11-08 02:34:31
字体:
来源:转载
供稿:网友

注:如果觉得有问题,可以一起讨论哦

 问题:有n盏灯,编号为1~n,第一个人把所有的灯打开,第二个人按下所有编号为2的倍数的开关(这些灯将被关掉),第三个人按下所有编号为3的倍数的开关(期中关掉的将被打开,打开的将被关掉)依此类推,一共有k个人,问最后有哪些灯开着,输入n和k,输出开着的灯的编号。k<=n<=1000

样例输入:

7 3

样例输出:

1 5 6 7

【分析】:用数组flag[],flag[0],flag[1],flag[2]....flag[n]表示灯1,2,3.。。。n是否开着。首先将他们全置为0,表示他们都开着,1则表示关了灯。

用例子来分析,7盏灯,3个人

因为flag[i]是会动态改变的,所以解题关键就是如何动态的去改变flag[i]的值

由图所见它和((i+1)%j==0)有关,如果i能整除j,那么flag[i]原来的值就要改变。

假设int a=((i+1)%j==0))=1

当j=2时,flag[2]由0变为1,flag[4]由0变为1,flag[6]由0变为1

当j=3时,flag[3]由0变为1,flag[6]由1变为0。

flag[i]到底和a有着什么样的关系?不难想象,他们是异或关系。

即flag[i]=((i+1)%j) xor flag[i]。

那我们要怎么样在代码中表示异或呢?

我们除了要判断i是否整除j,还要判断它是否和flag[i]的值是否一样,如果不一样,flag[i]就置1。

为了结果之间加空格,所以加了一个变量d,第一个结果肯定不能有空格,所以初始化d=0;当d=0时,不输出空格。d不等于0,就输出空格。

输入第一个结果后,d++;

所以代码很简单

       

                    /**开灯问题**/#include "stdafx.h"#include <string.h>#define maxn 1010int flag[maxn];int _tmain(int argc, _TCHAR* argv[]){	int n,k,d=0;	scanf("%d%d",&n,&k);	for(int i=0;i<n;i++){		flag[i]=0;//打开		//PRintf("%d/n",flag[i]);		for(int j=2;j<=k;j++){			if((i+1)%j==0){				if(((i+1)%j==0)==flag[i])flag[i]=0;				else flag[i]=1;			}			//printf("%d[%d]:%d/n",j,i,flag[i]);	}                 //结果之间加空格                         if(flag[i]==0){			if(d==0){printf("%d",i+1);d++;}		else printf(" %d",i+1);		} }	printf("/n");	return 0;}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选