• 合成反应


    链接: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
  • 相关阅读:
    Linux下环境变量配置方法梳理(.bash_profile和.bashrc的区别)
    Mac下安装配置Python2和Python3并相互切换使用
    精通Python自动化脚本
    idea之Git
    python面向对象之:细分类的组成成员
    new string("abc")创建了几个对象
    进程和线程的主要区别
    Leetcode 572 另一个树的子树
    Leetcode 二叉树的坡度
    Leetcode 559 N叉树的最大深度
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13271259.html
Copyright © 2020-2023  润新知