题解 | 小心火烛的歪
小心火烛的歪
https://www.nowcoder.com/practice/6cdb80dbb66c42eea179068a4afb25db
// 数学,组合,dfs 就好, 如果需要排列,也可以dfs,标记一下选过了什么,后面注意不选它就好了 #include<bits/stdc++.h> using namespace std; const int N=8; typedef pair<int,int> pii; set<pii> zw,kd; // 存杂物、空地的位置 set<pii> st[N]; // 存每一个计划烟花的位置 int n,m,q,idx=0; int ans=-1; vector<int> vet; void dfs(set<pii> kkdd,int ind,vector<int> t){ if(kkdd.empty()){ if(ans==-1){ ans=t.size(); vet=t; } else{ if(t.size()<ans){ ans=t.size(); vet=t; } } return ; } for(int i=ind;i<idx;i++){ bool sign=false; for(auto &j:st[i]){ if(kkdd.count(j)){ sign=true; break; } } if(sign){ vector<pii> arr; for(auto &j:st[i]){ if(kkdd.count(j)){ kkdd.erase(j); arr.push_back(j); } } t.push_back(i+1); dfs(kkdd,i+1,t); t.pop_back(); for(auto &j:arr){ kkdd.insert(j); } } } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); cin>>n>>m>>q; for(int i=0;i<n;i++){ string s; cin>>s; for(int j=0;j<m;j++){ if(s[j]=='0') kd.insert({i,j}); else zw.insert({i,j}); } } while(q--){ bool sign=false; for(int i=0;i<n;i++){ string s; cin>>s; for(int j=0;j<m;j++){ if(s[j]=='1'){ if(zw.count({i,j})) sign=true; st[idx].insert({i,j}); } } } if(sign) st[idx].clear(); idx++; } // for(auto &i:kd){ // cout<<i.first<<" "<<i.second<<" "; // } // cout<<endl; // for(int i=0;i<idx;i++){ // for(auto &j:st[i]){ // cout<<j.first<<" "<<j.second<<" "; // } // cout<<endl; // } // cout<<idx<<endl; vector<int> tt; dfs(kd,0,tt); if(ans!=-1){ cout<<ans<<endl; sort(vet.begin(),vet.end()); for(int i=0;i<vet.size();i++){ if(i==0) cout<<vet[i]; else cout<<" "<<vet[i]; } } else cout<<ans; return 0; }