Day32 洛谷P1876 开灯(先打表找规律)

题目背景

该题的题目是不是感到很眼熟呢?

事实上,如果你懂的方法,该题的代码简直不能再短。

但是如果你不懂得呢?那。。。(自己去想)

题目描述

首先所有的灯都是关的(注意是关!),编号为1的人走过来,把是一的倍数的灯全部打开,编号为二的的把是二的倍数的灯全部关上,编号为3的人又把是三的倍数的灯开的关上,关的开起来……直到第N个人为止。

给定N,求N轮之后,还有哪几盏是开着的。

输入格式

一个数N,表示灯的个数和操作的轮数

输出格式

若干数,表示开着的电灯编号

输入输出样例

输入 #1

5

输出 #1

1 4

说明/提示

1<=N<=2^40

80分答案(第五个点MLE)

#include<stdio.h>
int cnt;
int main(){
    int n;
    scanf("%d",&n);
    int i,j;
    int N=n+1;
    int a[N];
    for (i=1;i<=n;i++){
    	a[i]=0;
	}
    for (i=1;i<=n;i++){
    	for (j=i;j<=n;j+=i){
    		if (a[j]==0) a[j]=1;
    		else a[j]=0;
		}
	}
	for (i=1;i<=n;i++){
		if (a[i]==1){
			printf("%d ",i);
		}
	}
    return 0;
}

可以看出,以上代码虽然模拟了原题的过程,但是有弊端:如果数组开得太大(N太大),会爆掉导致数据点不通过。但是我们仍然可以通过这段代码找到规律,发现完全平方数的灯最后会亮着。于是我们可以将代码优化成一下简短的一个for循环。

AC答案

#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int i;
    for (i=1;i*i<=n;i++){
        printf("%d ",i*i);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值