合成反应

链接:https://www.nowcoder.net/acm/contest/78/I
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有机合成是指从较简单的化合物或单质化学反应合成有机物的过程。
有时也包括从复杂原料降解为较简单化合物的过程。
由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常要用加热、光照、加催化剂、加有机溶剂甚至加压等反应条件。
但是前人为有机合成提供了许多宝贵的经验。
现在已知有K总物质和N个前人已经总结出的合成反应方程式
小星想知道在现有M种物质的情况下 能否合成某些物质。

输入描述:

第一行输入四个整数 K,N,M,Q(K,N,M,Q<=1e5)
K表示一共K总物质
接下来N行 每行三个数字a b c(任意两个数可能相等)
表示a和b反应可以生成c 反应是可逆的
即可以通过c可以分解出a和b
接下来一行行然后输入m个数,表示m种原料(每一种原料都可以认为有无限多)
接下来Q个行Q个询问
对于每个询问
输出一个数字 x 判断是否可以通过一些反应得到第 x

输出描述:

可以得到Yes否则No
示例1

输入

10 3 4 10
1 2 3
4 5 6
2 5 7
3 4 5 8
1
2
3
4
5
6
7
8
9
10

输出

Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
No

说明

一共10总物质有第3,4,5,8 四种原料
查询每一种是否可以通过反应得到
首先通过3可以分解得到1 2
然后4 5合成6
2 5合成7
于是除了9 10都可以得到

我怕超时就用了向量
  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <vector>
  7 #define inf 0x3f3f3f3f
  8 using namespace std;
  9 //const double pi = acos(-1), e = exp(1);
 10 vector<int>a[100005];
 11 bool v[100005];
 12 bool ff[100005];
 13 void broad(int x)//如果x可以,那么x分解的都可以
 14 {
 15     int i;
 16     ff[x] = 1;
 17     for (i = 0; i<a[x].size(); i++)
 18     {
 19         int t1 = a[x].at(i);
 20         if (v[t1] == 0)
 21         {
 22             v[t1] = 1;
 23             if (a[t1].size() >= 2 && ff[t1] == 0)
 24             {
 25                 broad(t1);
 26             }
 27         }
 28     }
 29 }
 30 bool bb(int x)//如果x不可以,那么查看合成它的行不行
 31 {
 32     int i;
 33     for (i = 0; i < a[x].size(); i=i+2)
 34     {
 35         int t1 = a[x].at(i);
 36         int t2 = a[x].at(i + 1);
 37         if (v[t1] == 1 && v[t2] == 1)
 38         {
 39             v[x] = 1;
 40             if(a[x].size()>2) broad(x);
 41             return 1;
 42         }
 43     }
 44     return 0;
 45 }
 46 int main()
 47 {
 48     int k, n, m, q;
 49     int mm = -inf;
 50     int mi = inf;
 51     cin >> k >> n >> m >> q;
 52     memset(v, 0, sizeof(v));
 53     memset(ff, 0, sizeof(ff));
 54     int i;
 55     int x, y, z;
 56     for (i = 1; i <= 10005; i++) a[i].clear();
 57     for (i = 1; i <= n; i++)
 58     {
 59         cin >> x >> y >> z;
 60         if (x > mm) mm = x;
 61         if (x < mi) mi = x;
 62         if (y > mm) mm = y;
 63         if (y < mi) mi = y;
 64         if (z > mm) mm = z;
 65         if (z < mi) mi = z;
 66 
 67         a[z].push_back(x);
 68         a[z].push_back(y);
 69     }
 70     int p;
 71     for (p = 1; p <= m; p++)
 72     {
 73         cin >> x;
 74         v[x] = 1;
 75         if (a[x].size()>=2&&ff[x] == 0)
 76         {
 77             broad(x);//如果x可以,那么x分解的都可以
 78         }
 79     }
 80     bool up = 1;
 81     while (up)//查看合成它的
 82     {
 83         up = 0;
 84         for (i = mi; i <= mm; i++)
 85         {
 86             if (v[i]==0&&a[i].size() >= 2) 
 87             {
 88                 bool f ;
 89                 f = bb(i);
 90                 if (f) up = 1;
 91             }
 92         }
 93     }
 94     for (i = 1; i <= q; i++)
 95     {
 96         cin >> x;
 97         if (v[x] == 1) cout << "Yes" << endl;
 98         else cout << "No" << endl;
 99     }
100     return 0;
101 }
View Code

别人的代码更简单,不用向量也可以,直接暴力

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4  
 5 int main()
 6 {
 7     ios::sync_with_stdio(false);
 8     cin.tie(0);
 9  
10     int k, n, m, q;
11     cin >> k >> n >> m >> q;
12     bool book[k + 1];
13     memset(book, false, sizeof(bool) * (k + 1));
14  
15     int first1[n], first2[n], second[n];
16     for (int i = 0; i < n; ++i)
17         cin >> first1[i] >> first2[i] >> second[i];
18  
19     for (int i = 0; i < m; ++i)
20     {
21         int t;
22         cin >> t;
23         book[t] = true;
24     }
25  
26     bool flag = true;
27     while (flag)
28     {
29         flag = false;
30         for (int i = 0; i < n; ++i)
31         {
32             if (book[first1[i]] && book[first2[i]] && !book[second[i]])
33             {
34                 book[second[i]] = true;
35                 flag = true;
36             }
37             if (book[second[i]] && (!book[first1[i]] || !book[first2[i]]))
38             {
39                 book[first1[i]] = true;
40                 book[first2[i]] = true;
41                 flag = true;
42             }
43         }
44     }
45  
46     for (int i = 0; i < q; ++i)
47     {
48         int t;
49         cin >> t;
50         cout << (book[t] ? "Yes" : "No") << endl;
51     }
52  
53     return 0;
54 }
View Code

链接:https://www.nowcoder.net/acm/contest/78/I
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有机合成是指从较简单的化合物或单质化学反应合成有机物的过程。
有时也包括从复杂原料降解为较简单化合物的过程。
由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常要用加热、光照、加催化剂、加有机溶剂甚至加压等反应条件。
但是前人为有机合成提供了许多宝贵的经验。
现在已知有K总物质和N个前人已经总结出的合成反应方程式
小星想知道在现有M种物质的情况下 能否合成某些物质。

输入描述:

第一行输入四个整数 K,N,M,Q(K,N,M,Q<=1e5)
K表示一共K总物质
接下来N行 每行三个数字a b c(任意两个数可能相等)
表示a和b反应可以生成c 反应是可逆的
即可以通过c可以分解出a和b
接下来一行行然后输入m个数,表示m种原料(每一种原料都可以认为有无限多)
接下来Q个行Q个询问
对于每个询问
输出一个数字 x 判断是否可以通过一些反应得到第 x

输出描述:

可以得到Yes否则No
示例1

输入

10 3 4 10
1 2 3
4 5 6
2 5 7
3 4 5 8
1
2
3
4
5
6
7
8
9
10

输出

Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
No
No

说明

一共10总物质有第3,4,5,8 四种原料
查询每一种是否可以通过反应得到
首先通过3可以分解得到1 2
然后4 5合成6
2 5合成7
于是除了9 10都可以得到

我怕超时就用了向量
  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <vector>
  7 #define inf 0x3f3f3f3f
  8 using namespace std;
  9 //const double pi = acos(-1), e = exp(1);
 10 vector<int>a[100005];
 11 bool v[100005];
 12 bool ff[100005];
 13 void broad(int x)//如果x可以,那么x分解的都可以
 14 {
 15     int i;
 16     ff[x] = 1;
 17     for (i = 0; i<a[x].size(); i++)
 18     {
 19         int t1 = a[x].at(i);
 20         if (v[t1] == 0)
 21         {
 22             v[t1] = 1;
 23             if (a[t1].size() >= 2 && ff[t1] == 0)
 24             {
 25                 broad(t1);
 26             }
 27         }
 28     }
 29 }
 30 bool bb(int x)//如果x不可以,那么查看合成它的行不行
 31 {
 32     int i;
 33     for (i = 0; i < a[x].size(); i=i+2)
 34     {
 35         int t1 = a[x].at(i);
 36         int t2 = a[x].at(i + 1);
 37         if (v[t1] == 1 && v[t2] == 1)
 38         {
 39             v[x] = 1;
 40             if(a[x].size()>2) broad(x);
 41             return 1;
 42         }
 43     }
 44     return 0;
 45 }
 46 int main()
 47 {
 48     int k, n, m, q;
 49     int mm = -inf;
 50     int mi = inf;
 51     cin >> k >> n >> m >> q;
 52     memset(v, 0, sizeof(v));
 53     memset(ff, 0, sizeof(ff));
 54     int i;
 55     int x, y, z;
 56     for (i = 1; i <= 10005; i++) a[i].clear();
 57     for (i = 1; i <= n; i++)
 58     {
 59         cin >> x >> y >> z;
 60         if (x > mm) mm = x;
 61         if (x < mi) mi = x;
 62         if (y > mm) mm = y;
 63         if (y < mi) mi = y;
 64         if (z > mm) mm = z;
 65         if (z < mi) mi = z;
 66 
 67         a[z].push_back(x);
 68         a[z].push_back(y);
 69     }
 70     int p;
 71     for (p = 1; p <= m; p++)
 72     {
 73         cin >> x;
 74         v[x] = 1;
 75         if (a[x].size()>=2&&ff[x] == 0)
 76         {
 77             broad(x);//如果x可以,那么x分解的都可以
 78         }
 79     }
 80     bool up = 1;
 81     while (up)//查看合成它的
 82     {
 83         up = 0;
 84         for (i = mi; i <= mm; i++)
 85         {
 86             if (v[i]==0&&a[i].size() >= 2) 
 87             {
 88                 bool f ;
 89                 f = bb(i);
 90                 if (f) up = 1;
 91             }
 92         }
 93     }
 94     for (i = 1; i <= q; i++)
 95     {
 96         cin >> x;
 97         if (v[x] == 1) cout << "Yes" << endl;
 98         else cout << "No" << endl;
 99     }
100     return 0;
101 }
View Code

别人的代码更简单,不用向量也可以,直接暴力

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4  
 5 int main()
 6 {
 7     ios::sync_with_stdio(false);
 8     cin.tie(0);
 9  
10     int k, n, m, q;
11     cin >> k >> n >> m >> q;
12     bool book[k + 1];
13     memset(book, false, sizeof(bool) * (k + 1));
14  
15     int first1[n], first2[n], second[n];
16     for (int i = 0; i < n; ++i)
17         cin >> first1[i] >> first2[i] >> second[i];
18  
19     for (int i = 0; i < m; ++i)
20     {
21         int t;
22         cin >> t;
23         book[t] = true;
24     }
25  
26     bool flag = true;
27     while (flag)
28     {
29         flag = false;
30         for (int i = 0; i < n; ++i)
31         {
32             if (book[first1[i]] && book[first2[i]] && !book[second[i]])
33             {
34                 book[second[i]] = true;
35                 flag = true;
36             }
37             if (book[second[i]] && (!book[first1[i]] || !book[first2[i]]))
38             {
39                 book[first1[i]] = true;
40                 book[first2[i]] = true;
41                 flag = true;
42             }
43         }
44     }
45  
46     for (int i = 0; i < q; ++i)
47     {
48         int t;
49         cin >> t;
50         cout << (book[t] ? "Yes" : "No") << endl;
51     }
52  
53     return 0;
54 }
View Code

相关推荐