AcWing 116.パイロット兄弟(脳の再帰なし)

トピック

この質問は再帰には適していません。最初のいくつかの質問では、スイッチは1つのスイッチでしか変更できません(上記の状態は次のように変更できます:説明できないスイッチ)が、上のスイッチの状態はこの質問では、次のスイッチの変更から変更できます。

思考:この質問は暴力的である可能性があり、時間計算量が1億ベクトルコンテナ未満のコードでは、実行時間が3倍になるため、すべての状況を列挙します(yの合計コードを自分のコードと比較してテストします)あなた自身)
ここに画像の説明を挿入します

memcpyと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;
}

おすすめ

転載: blog.csdn.net/qq_47874905/article/details/114914879