95. 费解的开关

95. 费解的开关

好难。确实费解

在这里插入图片描述

最暴力方法:

每个格子有开和关两种操作,最暴力的方法就是对每个格子进行这两种操作,所以最后的时间复杂度是225 = 三千多万,每个开关有长度为5的for循环修改自己和上下左右四个方向,所以一共是一亿两千多万,会超时。

由题意可知:

  1. 顺序可以任意。即先按那个格子,最后都可以得到全为亮的结果。
  2. 每个格子最多只按一次。
  3. 设第i行已经确定,则要更改i+1行,只能通过修改i+2行更改i+1行的0

第i行已经确定,此时要修改第i+1行的0:如果直接更改i+1行,则势必会影响第i行,所以只能通过改变i+2行改变i+1行。所以如果确定了第1行,剩下的全能推出来。所以只需要枚举第一行的所有情况,将第一行确定,然后剩下i+1行的修改与否都可以通过i行j列是否为0来修改。

解题思路:

1. 如何枚举第一行操作

第一行有32种状态,分别对应5个位置。
这里用到了位运算的性质: 假设1表示翻转,0表示不动
设第一行的状态为 00000 则表示全不动,直接进行下面的i行的修改通过i+1行的修改确定。
设第一行的状态是11010 则表示第1 2 4 个灯需要翻转,对第一行第1 2 4列的灯进行翻转turn操作,然后再进行下面的第i行通过修改i+1行的修改确定。

2. 如何设置翻转自身和上下左右四个方向的turn函数

设置偏移量

int fx[5] = {0,-1,0,1,0};
int fy[5] = {0,0,-1,0,1};
for(int i=0;i<5;i++)
	x = x + fx[i];
	y = y + fy[i];

3. 时间复杂度

最坏情况下,第一行32种情况,然后一共修改了最多25个格子,每修改一个格子会牵扯5个格子,然后一共有500次询问,则最坏情况下的时间复杂度为32255*500 = 2 000 000 才两百万,足够了。


知识点

  1. 学会偏移量的设置
  2. 字符1和字符0的转换:0的ascii是110000 1的ascii是110001,所以只需要和1异或就能实现字符0和字符1 的转换
  3. 一般坐标的画法是向下为x轴正方向,向右为y轴正方向。
  4. 看一个数的二进制表示的第k位(位数从0开始)0还是1的方法:
    假设数为i ,i >>k & 1得到的就是这个数二进制下第k位为0 or 1

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N =  6; //还有个 \0
char g[N][N],backup[N][N];
int fx[5] = {0,-1,0,1,0};
int fy[5] = {0,0,-1,0,1};
void turn(int x,int y)
{
    for(int i=0;i<5;i++)
    {
        int a,b;
        a=x+fx[i];
        b=y+fy[i];
        g[a][b] ^= 1;
    }
}
int main()
{
    int T;
    cin>>T;
    while (T--)
    {
        int ans = 10;
        for(int i=0;i<5;i++)    
            cin>>g[i];
        
        //枚举第一行操作
        for(int op = 0; op < 32 ;op++)
        {
            int step = 0;
             memcpy(backup,g,sizeof g );	//先把最初的备份起来,后面再还原
            for(int i=0;i<5;i++)
            {
                if(op>>i & 1)	//& 1表示取最低位
                {
                    step++;
                    turn(0,i);
                }
            }
           
            for(int i=0;i<4;i++)
                for(int j=0;j<5;j++)
                {
                    if(g[i][j] == '0')
                    {
                        step++;
                        turn(i+1,j);
                    }
                }
            bool dark = false;
            for(int i=0;i<5;i++)
                if(g[4][i]=='0')
                {
                    dark = true;
                    break;
                }
            if(!dark) ans = min(ans,step);
             memcpy(g, backup, sizeof g);
        }
        if(ans < 6) cout<<ans<<"\n";
             else cout<<"-1\n";
    }
    
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
开关电源(Switching Power Supply)是现代电子设备中常用的一种电源模式,其设计文件通常以.schdoc作为文件后缀。 .schdoc文件是一种电路设计文件,使用专业的电子设计软件(如Altium Designer)创建和编辑。该文件包含了开关电源的原理图、元器件的连接和布局、参数设置等信息。 通过打开.schdoc文件,我们可以了解到开关电源的整体电路结构。这通常包括输入滤波电路、整流电路、功率电路以及控制电路。其中输入滤波电路用于滤除输入电源中的噪声和干扰;整流电路将交流电转换为直流电;功率电路负责将直流电转换为所需的输出电压和电流;控制电路用于监测和控制开关电源的工作状态。 在.schdoc文件中,我们还可以查看每个元器件的连接方式和布局。这些元器件包括开关管、变压器、电感、电容、二极管和控制芯片等。不同的开关电源设计可能使用不同的元器件组合和布局方式,以满足不同的电源要求。 另外,我们还可以在.schdoc文件中找到开关电源的参数设置。这些参数包括输入电压范围、输出电压和电流、效率、保护功能等。通过合理设置这些参数,可以使开关电源在工作过程中达到最佳的性能和稳定性。 总之,通过打开开关电源的.schdoc文件,我们可以全面了解开关电源的电路结构、元器件连接和布局以及参数设置,从而更好地理解和应用开关电源技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值