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

模拟

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[N];//左式化合物集合
vector<string>b[N];//右式化合物集合
vector<string>c;//存在的化合物
set<string>ans;//新生成化合物
bool found[N];//标记化学式是否已经合成 

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;
}
时间: 2024-11-09 00:44:30

[河南省ACM省赛-第五届] 试制品 (nyoj 542)的相关文章

[河南省ACM省赛-第五届] 最强DE 战斗力 (nyoj 541)

题解链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=541 几天前百度题解后用数学知识AC的,后来大牛说这是一道动态规划题. 网上的数学解题链接:http://blog.csdn.net/x314542916/article/details/8204583 d(i) = max{d(j)*d(n-j) | 1<= j <=n/2}; 用Java写比较简单 import java.math.BigInteger; import java.u

第五届河南省acm省赛 最强DE 战斗力

最强DE 战斗力 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 春秋战国时期,赵国地大物博,资源非常丰富,人民安居乐业.但许多国家对它虎视眈眈,准备联合起来对赵国发起一场战争. 显然,面对多个国家的部队去作战,赵国的兵力明显处于劣势.战斗力是决定战争成败的关键因素,一般来说,一支部队的战斗力与部队的兵力成正比.但当把一支部队分成若干个作战队伍时,这个部队的战斗力就会大大的增强. 一支部队的战斗力是可以通过以下两个规则计算出来的: 1.若一支作战队伍的兵力为N,则这

[河南省ACM省赛-第三届] 网络的可靠性 (nyoj 170)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=170 根据题意,需要找到度数为1的结点个数,如下图: #include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define N 10002 vector<int> g[N]; int main() { freo

[河南省ACM省赛-第三届] 房间安排 (nyoj 168)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=168 分析:找到一天中需要最多的房间即可 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 200 int day[N];//day[i] 第i天的最多房间数 int main() { fre

[河南省ACM省赛-第三届] AMAZING AUCTION (nyoj 251)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=251 规则: 1.若某竞标价唯一,则胜出 2.若不存在唯一竞标价,则投标次数最少竞标价中标,存在多个时,选择价钱最低且最先投此价钱的为中标 #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 102 #define M 1002 struct N

[河南省ACM省赛-第三届] 素数 (nyoj 169)

#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define N 1100 #define INF 0x7fffffff bool prime[N]; void init() { memset(prime, true,

[河南省ACM省赛-第三届] BUYING FEED (nyoj 248)

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 352 /* 重量*单价+重量*距离 = 重量*(距离+单价) 预处理单价 贪心:优先买价格低的 */ struct Node { int p;// p = (单价+距离) int w; }c[N]; bool cmp(Node a, Node b)

[河南省ACM省赛-第四届] 表达式求值(nyoj 305)

栈的模拟应用: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; string getPostfixExp(string s) { stack<char> sta;// d

[河南省ACM省赛-第四届] 序号互换 (nyoj 303)

相似与27进制的转换 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; int main(){ int t; string s; cin>>t; while(t--) {