2019大疆笔试题 —— 两个电路板(开关闭开和灯泡明暗)
题目描述:
小A是一名DIY爱好者,经常制作一些有趣的东西。
今天,小A突然想要来做这样一个东西。小A现在有两块同样大小为n×m,有n×m块大小为1×1小电路板拼成的矩形电路板,假设叫做电路板A和电路板B。电路板A上每个小电路板都是一个开关,电路板B上每个小电路板上都是一盏电灯泡。A与B之间存在如下关系:对于B上的某盏灯Bij的开关控制,有A上第i行与第j列所有开关并联控制。即:
现给一矩阵,表示B上灯泡的明暗状态,问是否存在一种A的开关状态,能够满足给出的B上的灯泡开关情况,如果有输出YES,没有输出NO。
输入描述:
第一行,n和m表示电路板的长和宽,(1<=n,m<=1000)
接下来n行,每行有m个由空格隔开的数字,0或1。0表示灯泡暗,1表示灯泡亮
输出描述:
输出一行,如果存在至少一种A的开关设置方式,能够使得B上灯泡明亮和给出的状态矩阵相同,则输出YES;不存在则输出NO。
示例:
样例1:
输入:
2 3
1 1 1
1 1 1
输出:
YES
样例2:
输入:
2 3
1 1 0
0 1 1
输出:
NO
思路分析:
(1) 定义两个二维vector:A和B;其中A存储开关的开闭情况,B储存灯泡亮暗状态;
(2) 将开关vectorA全置为开("1"为开,"0"为闭);遍历一遍vector B(灯泡),将灯泡为暗("1"为亮,"0"为暗)的所在行和列的开关置为闭("0");
(3) 再遍历一遍vector A(开关),判断所有亮着的灯泡的所在行和列是否存在状态为开的开关,若所有亮着的灯泡均存在着状态为开的开关,则输出"Yes",否则输出"No"
代码如下:#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n, m;
while (cin >> n >> m)
{
vector<vector<int>> A(n, vector<int>(m, 1)); // 开关 开为1,关为0
vector<vector<int>> B(n, vector<int>(m, 0)); // 灯泡 亮为1,暗为0
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
cin >> B[i][j];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (B[i][j] == 0)
{
for (int p = 0; p < n; p++)
A[p][j] = 0;
for (int q = 0; q < m; q++)
A[i][q] = 0;
}
}
}
bool result = true;
for (int i = 0; i < n ; i++)
{
int flag1 = true;
for (int j = 0; j < m ; j++)
{
int flag2 = false;
if (B[i][j] == 1)
{
for (int p = 0; p < n ; p++)
{
if (A[p][j] == 1)
flag2 = true;
}
for (int q = 0; q < m; q++)
{
if (A[i][q] == 1)
flag2 = true;
}
if (flag2)
continue; // 一个亮着的灯泡所在行和列有开关开着,接着
else // 判断下一个直至所有亮着的灯泡所在行和列均有开关开着;
{
result = false; // 有任意一个不满足条件则退出循环,输出"No";
flag1 = false;
break;
}
}
}
if (!flag1)
break;
}
if (result)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}