(开灯问题)(B - The Pilots Brothers' refrigerator)(洛谷T74791 飞行员兄弟)

B - The Pilots Brothers’ refrigerator

The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.

There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.

The task is to determine the minimum number of handle switching necessary to open the refrigerator.

Input
The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.

Output
The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.

Sample Input
-+--
----
----
-+--
Sample Output
6
1 1
1 3
1 4
4 1
4 3
4 4

洛谷T74791 飞行员兄弟

题目描述
“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。

已知每个把手可以处于以下两种状态之一:打开或关闭。

只有当所有把手都打开时,冰箱才会打开。

把手可以表示为一个4х4的矩阵,您可以改变任何一个位置[i,j]上把手的状态。

但是,这也会使得第i行和第j列上的所有把手的状态也随着改变。

请你求出打开冰箱所需的切换把手的次数最小值是多少。

输入输出格式
输入格式:
输入一共包含四行,每行包含四个把手的初始状态。

符号“+”表示把手处于闭合状态,而符号“-”表示把手处于打开状态。

至少一个手柄的初始状态是关闭的。

输出格式:
第一行输出一个整数N,表示所需的最小切换把手次数。

接下来N行描述切换顺序,每行输入两个整数,代表被切换状态的把手的行号和列号,数字之间用空格隔开。

输入输出样例
输入样例#1: 复制
-+--
----
----
-+--
输出样例#1: 复制
6
1 1
1 3
1 4
4 1
4 3
4 4
说明
1≤i,j≤4

思路:

一种比较巧妙的方法
  先看一个简单的问题,如何把’+‘变成’-'而不改变其他位置上的状态?
  答案是将该位置(i,j)及位置所在的行(i)和列(j)上所有的位置更新一次,结果:
   该位置被更新了7次 ,
  相应行(i)和列(j)的位置被更新了4次 ,
  剩下的被更新了2次
  被更新 偶数次 的位置不会造成最终状态的改变.

通过思考我们可以验证,某一个单元格内符号为‘+’,同时对其所在行与所在列的所有单元格进行操作(其本身只操作一次),原‘+’单元格元素便会变成‘-’,其余单元格符号均不发生改变。

所以我们可以这么做,对每个‘+’所在行列的单元格进行操作(其本身只操作一次),统计每个单元格被操作的次数,输出奇数次操作数的单元格即可。

AC代码:

#include<iostream>
using namespace std;
int I[5][5]={0};//处理
char L[5][5];//输入
int main()
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            cin>>L[i][j];
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(L[i][j]=='+')
            {
                for(int k=0;k<4;k++)
                {
                    I[k][j]++;//列
                    I[i][k]++;//行
                }
                I[i][j]--;//上边多加了一次
            }
        }
    }
    int ans=0;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(I[i][j]%2!=0)
                ans++;
    cout<<ans<<endl;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(I[i][j]%2!=0)
                cout<<i+1<<' '<<j+1<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43250284/article/details/89073823
今日推荐