【问题描述】
给定n个开关和m个灯,第i个开关只能打开部分灯。矩阵a包含n行m列,当aij=1时表示开关i可以打开灯j,否则aij=0。
开始时所有的m个灯都是关着的。
开关只能从状态"关"到"开"。这意味着,对于每个可以打开某个灯的开关,无论你按多少次,这个灯都是开的。
确保当你按下所有开关时,所有的灯都能打开,考虑是否可以忽略其中某个开关也能打开所有的灯。
你的任务是确定是否存在这样的开关可以忽略,而使用其余的n-1个开关来打开所有m个灯。
【输入形式】
输入第1行包含两个整数n和m(1<=n, m<=2000),表示开关的数量和灯的数量。
接下来的n行,每行包含m个字符,字符aij=1时表示开关i可以打开灯j,否则aij=0。
【输出形式】
如果存在这样的可以忽略的开关,而使用其他n-1个开关打开所有的m个灯,输出"YES",否则输出"NO"。
【样例输入】
4 5
10101
01000
00111
10000
【样例输出】
YES
题解
思路
- 1.首先我们要对每一列求和,那么我们得到m个和,如果有一个和为0就说明:这个灯没被开过呗(当然要记录结果哦)
- 2.我们用这个和减去之前n中某一次(遍历),如果有一个值为0就说明不行,我们遍历下一个。
- 3.有一次遍历每个值都不为0,那么就说明n-1个开关可以开m个灯
- 4.遍历完都没找到那就找不到了
代码
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
vector<int> res(m,0);
vector<vector<int> > map(m);
for(int i=0;i<n;i++){
string s;
cin>>s;
for(int j=0;j<m;j++){
map[i].push_back(s[j]-'0');//记录输入,方便后面减去
res[j]+=map[i][j];//求出m个灯每个灯可以被多少个开关控制
}
}
for(int i=0;i<n;i++){
int j;
for(j=0;j<m;j++){
int temp=res[j]-map[i][j];
if(temp<=0) break;//减去某一次开关。如果有个灯没亮,说明不能不开这个开关
}
if(j==m) {
cout<<"YES"<<endl;return 0;//j==m说明减去后,灯还是全亮的
}
}
cout<<"NO"<<endl;//一直没yes就no了呗
return 0;
}