您的位置:首页 > 其它

[河南省ACM省赛-第五届] 试制品 (nyoj 542)

2015-04-06 12:06 417 查看
模拟

a 反应物集合 ; b 生成物集合; c 存在的化合物或单质集合; ans 新生成化合物集合

1、如果反应无均在已生成的化合物集合中,则完成反应,将合成物加入c集合

2、对每个方程式的反应物进行排序,方便加速查找

3、不停的搜索,直到没有新化合物生成。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define N 402

vector<string>a
;//左式化合物集合
vector<string>b
;//右式化合物集合
vector<string>c;//存在的化合物
set<string>ans;//新生成化合物
bool found
;//标记化学式是否已经合成

int main() {
freopen("d:\\in.txt", "r", stdin);
int n, m;
while(cin>>n) {
memset(found, false, sizeof(found));
for(int i=0; i<n; i++){
a[i].clear();
b[i].clear();
}
c.clear();
ans.clear();
string expr, str;
for(int i=0; i<n; i++) {
cin>>expr;
int mid = expr.find("=", 0);
expr[mid] = '+';
expr += "+";
int len = expr.size();
for(int j = 0; j<mid+1; j++){
if(expr[j] != '+')
str.push_back(expr[j]);
else{
a[i].push_back(str);
str.clear();
}
}
for(int j = mid+1; j<len; j++){
if(expr[j] != '+')
str.push_back(expr[j]);
else{
b[i].push_back(str);
str.clear();
}
}
}
cin>>m;
for(int i=0; i<m; i++){
cin>>expr;
c.push_back(expr);
}
for(int i=0; i<n; i++){//排序方便查找
sort(a[i].begin(), a[i].end());
}
bool hasnext = true;
while(hasnext){
hasnext = false;
for(int k=0; k<n; k++){
if(found[k]) continue;
string first = a[k][0];
if(find(c.begin(), c.end(), first) != c.end()){//如果方程式的第一个元素存在
int size = a[k].size();
int i = 1;
for( ; i<size; i++){//在已经存在的化合物集合中查找化学式剩余的化合物
if(find(c.begin()+1, c.end(), a[k][i]) == c.end())
break;
}
if(i == size) {//如果左式完全匹配
found[k] = true;
hasnext = true;
for(vector<string>::iterator it = b[k].begin(); it != b[k].end(); it++){
if(find(c.begin(), c.end(), *it) == c.end()) {
c.push_back(*it);
ans.insert(*it);
}
}
}
}
}
}
cout<<ans.size()<<endl;
for(set<string>::iterator it = ans.begin(); it != ans.end(); it++)
cout<<*it<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: