AcWing 116. Pilot brothers (no brain recursion)

topic

This question is not suitable for recursion, because in the first few questions, a switch can be changed by only one switch (the state above can be changed from the following, such as: the inexplicable switch), but the state of the upper switch in this question can be changed from the following Any switch changes.

Thinking: Enumerate all the situations, because this question can be violent, and the code with a time complexity of less than 100 million
Insert picture description here
vector containers will increase the running time by 3 times (compare the total code of y with your own, and test it yourself)

Learn to use memcpy and sizeof

#include <cstring>//因为y总用的vector容器,我将他的代码进行了改变,蓝桥杯vector会有警告 
#include <iostream> 
#include <algorithm>
#include <cstdio>
using namespace std;

const int N = 5;

char g[N][N], backup[N][N];
int back[25][N];//back用于输出最后答案,每次发现步数少到都会复制到back中 

int get(int x, int y)
{
    
    
    return x * 4 + y;//将二维数组转换为一维,进行二进制操作 (与48行对应) 
}

void turn_one(int x, int y)
{
    
    
    if (g[x][y] == '+') g[x][y] = '-';//符号转化 
    else g[x][y] = '+';
}

void turn_all(int x, int y)
{
    
    
    for (int i = 0; i < 4; i ++ )
    {
    
    
        turn_one(x, i);
        turn_one(i, y);
    }

    turn_one(x, y);
}

int main()
{
    
    
    for (int i = 0; i < 4; i ++ ) cin >> g[i];

    int  cnt=0;
    for (int op = 0; op < 1 << 16; op ++ )// 1 << 16  表示为2的16次方 
    {
    
    
        int ans[25][N],k=0;
        
        memcpy(backup, g, sizeof g);        // 将g备份

        // 进行操作
        for (int i = 0; i < 4; i ++ )
            for (int j = 0; j < 4; j ++ )
                if (op >> get(i, j) & 1)//当二进制的位数为1时,需要操作 
                {
    
    
                    ans[k][0]=i;
					ans[k++][1]=j;
                    turn_all(i, j);
                }

        // 判断所有灯泡是否全亮
        bool has_closed = false;
        for (int i = 0; i < 4; i ++ )
            for (int j = 0; j < 4; j ++ )
                if (g[i][j] == '+')
                    has_closed = true;

        if (has_closed == false)
        {
    
    
            if (cnt==0 || cnt > k) {
    
    //当前的移动步数小于cnt时,将k赋值给cnt 
            	cnt = k;
            	 memcpy(back, ans, sizeof ans); //将ans数组复制给back 
			}
        }

        memcpy(g, backup, sizeof g);        // 还原g数组 
    }
    cout << cnt << endl;
    for(int i=0;i<cnt;i++)
    {
    
    
    	printf("%d %d\n",back[i][0]+1,back[i][1]+1);//数组需要加一(你懂!) 
	}

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_47874905/article/details/114914879