1 条题解

  • 0
    @ 2025-5-20 20:14:28

    题意分析:

    输入格式:输入包含四行,每行四个字符,表示冰箱门上16个把手的初始状态。“+”表示闭合,“−”表示打开。 目标:通过最少的操作次数,使所有把手都处于打开状态。 操作规则:每次操作可以选择一个位置[i, j],改变该位置的行[i]和列[j]的状态。例如,如果某个位置从“−”变为“+”,则该行和该列的所有位置都会从“−”变为“+”或从“+”变为“−”。 输出格式:第一行输出最小操作次数N,接下来N行每行输出一个操作,格式为“i j”,表示对第i行第j列进行一次操作。

    解题思路:

    暴力枚举法:

    遍历所有可能的操作组合,计算每种组合所需的最小操作次数。 检查每种组合是否能够使所有把手都打开。 记录并返回满足条件的最小操作次数及对应的序列。 位运算优化:

    将矩阵的状态表示为一个整数变量,其中每一位对应一个把手的状态(0表示关闭,1表示打开)。 使用位运算快速判断某次操作是否会导致目标状态的达成。 通过枚举所有可能的操作组合,找到最小操作次数。 深度优先搜索(DFS):

    使用递归方式逐步尝试不同的操作组合。 在递归过程中记录当前状态,并剪枝以减少不必要的计算。 状态压缩:

    将矩阵的状态压缩为一个整数变量,减少存储空间。 使用状态压缩结合位运算或DFS进行求解。

    算法标签:

    暴力枚举 位运算 深度优先搜索(DFS) 状态压缩

    #include <iostream>
    using namespace std;
     
    bool map[4][4]={0};
    bool flag=false;
    int step;
    int res[16][2]={0};
     
    //judge whether to an end
    bool isOver()
    {
    	int i,j;
    	for(i=0;i<4;i++)
    	{
    		for(j=0;j<4;j++)
    		{
    			if(map[i][j]==0)
    			{
    				return false;
    			}
    		}
    	}
    	return true;
    }
     
    void change(int row,int col)
    {
    	int i;
    	map[row][col]=!map[row][col];
    	for(i=0;i<4;i++)
    	{
    		map[row][i]=!map[row][i];
    	}
    	for(i=0;i<4;i++)
    	{
    		map[i][col]=!map[i][col];
    	}
    }
     
    void dfs(int row,int col,int deep)
    {
    	if(deep==step)
    	{
    		flag=isOver();
    		return;
    	}
    	if(flag || row==4)  
        {  
            return;  
        }  
        change(row,col);
    	res[deep][0] = row;
    	res[deep][1] = col;
        if(col<3)  
        {  
            dfs(row,col+1,deep+1);  
        }  
        else  
        {  
            dfs(row+1,0,deep+1);  
        }  
        change(row,col);  
        if(col<3)  
        {  
            dfs(row,col+1,deep);  
        }  
        else  
        {  
            dfs(row+1,0,deep);  
        }    
    }
    //1:open,0:close
    int main()
    {
    	char temp;
    	int i,j;
    	//initial
    	for(i=0;i<4;i++)
    	{
    		for(j=0;j<4;j++)
    		{
    			cin>>temp;
    			if('-'==temp)
    			{
    				map[i][j]=1;
    			}
    		}
    	}
    	//function
    	for(step=1;step<=16;step++)
    	{
    		dfs(0,0,0);
    		if(flag)
    		{
    			break;
    		}
    	}
    	//result
    	cout<<step<<endl;
    	for(i=0;i<step-1;i++)
    	{
    		cout << res[i][0] + 1 << " " << res[i][1] + 1 << endl;
    	}
    	cout << res[step - 1][0] + 1 << " " << res[step - 1][1] + 1;
    	//system("pause");
    	return 0;
    }
    • 1

    信息

    ID
    1966
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者