题目描述:
有 n 盏灯和 m 个开关,每个按钮可以同时控制这 n 盏灯。
对于操作(1),如果那个灯开着,则将对应的灯关闭,否则不管;
对于操作(-1),如果那个灯关着,则将对应的灯打开,否则不管;
对于操作(0),表示不操作该盏灯;
现在灯全是开着的,请你求出最少多少次操作可以关掉所有灯。
输入格式:
第一行包含两个整数 n 和 m。
接下来 m 行,包含 n 个正整数 -1/0/1。1 表示关掉,-1 表示打开,0 表示不操作该盏灯。
输出格式:
输出一行一个整数,表示答案。
样例输入:
3 2
1 0 1
-1 1 0
样例输出:
2
数据规模:
对于100%数据 n<=10,m<=100
样例解释:
先进行第二个开关的操作(-1 1 0),会使得3盏灯为:开 关 开
再进行第一个开关的操作(1 0 1),会使得3盏灯为:关 关 关
dfs版:
#include<bits/stdc++.h>
using namespace std;
map<unsigned long long,bool>mp;
int n,m,v[101][11],d=-1,ans=1;
bitset<11>x;
void dfs(bitset<11>a){
if(!a.none()){
cout<<ans;
exit(0);
}for(int i=0;i<m;i++){
if(d==i)continue;
bitset<11>t=a;
for(int j=0;j<n;j++){
if(v[i][j]==1)t.reset(j);
if(v[i][j]==-1)t.set(j);
}if(!mp.count(t.to_ulong())){
mp[t.to_ulong()]=1;
ans++;
dfs(t);
ans--;
mp.erase(t.to_ulong());
}
}
}int main(){
cin>>n>>m;
for(int i=0;i<m;i++)for(int j=0;j<n;j++)cin>>v[i][j];
x.reset();
mp[x.to_ulong()]=1;
dfs(x);
return 0;
}
bfs版:
#include<bits/stdc++.h>
using namespace std;
int n,m,v[101][11];
bool f[1024];
bitset<10>x,y;
struct node{
bitset<10>b;
int step;
}t;
queue<node>q;
int main(){
cin>>n>>m;
for(int i=0;i<m;i++)for(int j=0;j<n;j++)cin>>v[i][j];
q.push({x,1});
f[x.to_ulong()]=1;
while(!q.empty()){
t=q.front();
q.pop();
if(!t.b.none()){
cout<<t.step;
return 0;
}for(int i=0;i<m;i++){
y=x;
for(int j=0;j<n;j++){
if(v[i][j]==-1)y.set(j);
if(v[i][j]==1)y.reset(j);
}if(!f[y.to_ulong()]){
q.push({y,t.step+1});
f[y.to_ulong()]=1;
}
}
}cout<<-1;
return 0;
}
全部50分qwq