概述
题目地址:
http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=77
描述
有 n 盏灯,编号为 1~n ,第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有 k 个人,问最后有哪些灯开着?输入: n 和 k ,输出开着的灯编号。 k ≤ n ≤ 1000
输入
输入一组数据: n 和 k
输出
输出开着的灯编号
样例输入
7 3
样例输出
有 n 盏灯,编号为 1~n ,第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有 k 个人,问最后有哪些灯开着?输入: n 和 k ,输出开着的灯编号。 k ≤ n ≤ 1000
输入
输入一组数据: n 和 k
输出
输出开着的灯编号
样例输入
7 3
样例输出
1 5 6 7
代码:
#include <stdio.h>
#include <stdlib.h>
//处理数据
static void handlerData(int n,int k);
//打印结果
static void printArray(int *pArr,int len);
int main()
{
int n = 0;
int k = 0;
scanf("%d %d",&n,&k);
handlerData(n,k);
return 0;
}
//打印结果
static void handlerData(int n,int k)
{
int *pArr = (int*)malloc((n+1)*sizeof(int));
//赋值 1代表打开,-1代表关闭
int index = 0;
for(;index <= n;++index)
{
pArr[index] = 1;
}
//每个数的倍数循环遍历-1的时候全部打开,已经在赋值的时候处理
int flag = 2;
for(;flag<=k;++flag)
{
//倍数开关
int step = 1;
//临时保存倍数形成的索引
int stepIndex = step*flag;
//终止条件-索引都要在n范围之内
while(step<=n && stepIndex<=n)
{
pArr[stepIndex] *= -1;
++step;
stepIndex = step * flag;
}
}
//输出结果
printArray(pArr,n+1);
free(pArr);
}
//打印结果
static void printArray(int *pArr,int len)
{
int index = 1;
for(;index <= len;++index)
{
if(pArr[index] == 1)
{
printf("%d ",index);
}
}
printf("n");
}
#include <stdlib.h>
//处理数据
static void handlerData(int n,int k);
//打印结果
static void printArray(int *pArr,int len);
int main()
{
int n = 0;
int k = 0;
scanf("%d %d",&n,&k);
handlerData(n,k);
return 0;
}
//打印结果
static void handlerData(int n,int k)
{
int *pArr = (int*)malloc((n+1)*sizeof(int));
//赋值 1代表打开,-1代表关闭
int index = 0;
for(;index <= n;++index)
{
pArr[index] = 1;
}
//每个数的倍数循环遍历-1的时候全部打开,已经在赋值的时候处理
int flag = 2;
for(;flag<=k;++flag)
{
//倍数开关
int step = 1;
//临时保存倍数形成的索引
int stepIndex = step*flag;
//终止条件-索引都要在n范围之内
while(step<=n && stepIndex<=n)
{
pArr[stepIndex] *= -1;
++step;
stepIndex = step * flag;
}
}
//输出结果
printArray(pArr,n+1);
free(pArr);
}
//打印结果
static void printArray(int *pArr,int len)
{
int index = 1;
for(;index <= len;++index)
{
if(pArr[index] == 1)
{
printf("%d ",index);
}
}
printf("n");
}
通过1 和 *-1的形式,处理每次开关的触发,另外为了计数方便,申请了n+1长度的数组,
第一个索引位置0闲置不用。
另外在判断具体倍数的时候,没有遍历数组%当前数 == 0进行判断,而是直接使用了倍数求得索引
如此可以减少计算量。也就是说针对数组数据的访问操作,如果能够通过下标操作的,
就尽可能的不要遍历所有的数据来减少计算量。
转载于:https://www.cnblogs.com/sharpfeng/p/5141750.html
最后
以上就是聪慧小蝴蝶为你收集整理的23-语言入门-23-开灯问题的全部内容,希望文章能够帮你解决23-语言入门-23-开灯问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复