SWUN_2016级新生校赛_开关灯

本文介绍了一个经典的开关灯问题,给出了一种高效的解决方法,并通过代码实现了该算法。问题描述为:给定一串灯的初始状态,求最少需要按几次开关使所有灯关闭。文章详细解释了解决方案并附带AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                    **开关灯**

时间限制(普通/Java) : 1000 MS/ 10000 MS 运行内存限制 : 65536 KByte
总提交 : 43 测试通过 : 16

描述
paodekuai学长最近在复习考研题目,这天他被考研题目折磨的死去活来,于是决定做一道水题来放松心情。题目内容如下:有L盏灯编号为1 ~ L,有L个开关编号也为1 ~ L,编号为i的开关决定了编号为i的倍数(含i自身)的灯的状态(每按下开关,对应的灯的状态反转)。现给一个长度为L的字符串代表L盏灯的初始状态,字符串仅有‘Y’和‘N’组成,‘Y’代表开,‘N’代表关。求总共最少需要按几次开关使得所有的的灯被关上。

输入
本题为单组数据评测。
第一行一个整数L (1 ≤ L ≤ 105),表示灯的个数
第二行一个长度为L的字符串,每个字符都是‘Y’或‘N’,表示灯的初始状态。

输出
输出一个整数ans,表示关上所有灯所需的最少操作数(每按下任何一个开关视为一次操作)。

样例输入
9
YNYNYNYNY
样例输出
2
提示
对于所给样例,可以先按一下2号开关,变成状态 YYYYYYYYY, 之后再按下1号开关变成状态NNNNNNNNN,不难证明,不存在操作次数更少的关灯方法。

题目来源
By YG_PP

思路:
这是一个开关灯问题,很清楚地知道每个数只有 0 1 两种状态,按道理来说可以用动态规划来写。可惜我不会=。=

以下是ac代码思路:
因为第 i 盏灯的开关,可以直接影响到 2 * i 及以后所有 i 的倍数的灯的开关情况。所以最优方案只有从头往后的扫,这样就变成一个简单的模拟题了。

以下是ac代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int maxn=1e5+5;
char s[maxn+5];
int a[maxn+5];

int main()
{
    int k;
    scanf ("%d",&k);
    scanf ("%s",s+1);
    int len=strlen(s+1);
    for (int i=1;i<=len;i++)//把 Y N 的状态 变成 0 1 状态,也可以不变。
    {
        if (s[i]=='Y') a[i]=1;
        else a[i]=0;
    }

    long long cnt=0;
    for (int i=1;i<=len;i++)
    {
        if (a[i]==1)
        {
            cnt++;
            a[i] = !a[i];
            for (int j=2*i;j<=len;j+=i) a[j] = !a[j];//Eratosthenes 筛法
        }
    }

    printf ("%lld\n",cnt);
}

P.S. 说到底这还是一条简单的语言题,用嘴很容易就能说出来,当时没做出来,到底还是语言不过关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值