一开始题目测试点1、5挂了,咋都找不到答案,于是借鉴大佬的代码
https://blog.csdn.net/qq_52661062/article/details/114701346
写了一遍(代码2),感觉思路清晰多了,又重新检查了自己代码,递归 T_T 答案出口条件 出错( 居然写成了beg >= equ.size())。
代码1:
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
struct Equ{
vector<int> rea;
int pro;//reactant, products
};
vector<Equ> equ;
vector<int> rea, pro, ans;// 反应物 生成物 答案
int pro_order[100];//存入 生成物优先级
int vis_rea[100], vis_pro[100];//0 表示没有(对应测试点2) 1表示没用过 2表示已经使用
bool over;
bool no_repeat(Equ e){
for(auto x: e.rea)
if(vis_rea[x] != 1)
return false;
return true;
}
void mark_used(Equ e, int mark){
for(auto x: e.rea)
vis_rea[x] = mark;
}
void print_ans(){
for(int i=0; i<ans.size(); i++){
Equ e = equ[ans[i]];
printf("%02d ", e.rea[0]);
for(int j=1; j<e.rea.size(); j++)
printf("+ %02d ", e.rea[j]);
printf("-> ");
printf("%02d\n", e.pro);
}
}
void dfs(int beg){
if(over) return;
if(ans.size() == m){//答案出口
print_ans();
over = true;
return;
}
if(beg >= equ.size()) return;
for(int i=beg; i<equ.size(); i++){
if(over) return;
if(no_repeat(equ[i]) && vis_pro[equ[i].pro] == 1){
vis_pro[equ[i].pro] = 2;
ans.push_back(i);
mark_used(equ[i], 2);
dfs(i+1);
mark_used(equ[i], 1);
vis_pro[equ[i].pro] = 1;
ans.pop_back();
}
}
}
bool cmp(Equ a, Equ b){
if(pro_order[a.pro] == pro_order[b.pro]){
for(int i=0; i<min(a.rea.size(), b.rea.size()); i++){
if(a.rea[i] != b.rea[i])
return a.rea[i] < b.rea[i];
}
return a.rea.size() < b.rea.size();
}
return pro_order[a.pro] < pro_order[b.pro];
}
int main(){
cin>>n;
for(int i=0, x; i<n; i++){
cin>>x;
rea.push_back(x);
vis_rea[x] = 1;
}
cin>>m;
for(int i=0, x; i<m; i++){
cin>>x;
pro.push_back(x);
vis_pro[x] = 1;
pro_order[x] = i+1;
}
cin>>k;
for(int i=0; i<k; i++){
Equ e;
string s;
while(cin>>s, s!="->"){
if(s != "+"){
e.rea.push_back(stoi(s));
}
}
cin>>s;
e.pro = stoi(s);
equ.push_back(e);
}
for(int x : pro){
if(vis_rea[x] == 1){
Equ e;
e.rea.push_back(x);
e.pro = x;
equ.push_back(e);
}
}
sort(equ.begin(), equ.end(), cmp);
dfs(0);
return 0;
}
代码2:
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
vector<vector <int>> react[100], ans;//react[i][j][k] i生成物 的 第j个反应物数组 的 第k个反应物
vector<int> rea, pro;
int vis_rea[100];//0 表示没有(对应测试点2) 1表示没用过 2表示已经使用
bool no_used(vector<int> a){//使用检测
for(auto x: a)
if(vis_rea[x] != 1)
return false;
return true;
}
void mark_used(vector<int> a, int mark){//使用标记
for(auto x: a)
vis_rea[x] = mark;
}
void print_ans(){//输出答案
for(int i=0; i<m; i++){
printf("%02d ", ans[i][0]);
for(int j=1; j<ans[i].size(); j++)
printf("+ %02d ", ans[i][j]);
printf("-> ");
printf("%02d\n", pro[i]);
}
}
bool dfs(int i){
if(i >= m){
print_ans();
return 1;
}
for(auto r: react[pro[i]]){
if(no_used(r)){
mark_used(r, 2);//标记用过了
ans.push_back(r);
if(dfs(i+1)) return 1;//按 pro数组中反应物 输入顺序一个个找
mark_used(r, 1);//取消标记
ans.pop_back();
}
}
return 0;
}
int main(){
cin>>n;
for(int i=0, x; i<n; i++){
cin>>x;
rea.push_back(x);
vis_rea[x] = 1;
}
cin>>m;
for(int i=0, x; i<m; i++){
cin>>x;
pro.push_back(x);
if(vis_rea[x]){//添加 x -> x
vector<int> t(1,x);
react[x].push_back(t);
}
}
cin>>k;
for(int i=0, p; i<k; i++){//输入
string s;
vector<int> t;
while(cin>>s, s!="->")
if(s != "+")
t.push_back(stoi(s));
cin>>p;
react[p].push_back(t);
}
for(int p: pro)//将生成物 对应的多个 反应物数组排序
sort(react[p].begin(), react[p].end());
dfs(0);
return 0;
}