• 399. Evaluate Division


    问题:

    给定 一组【被除数,除数,商】的数组,根据已知的等式关系,

    求要求的一组【被除数,除数】的商。

    Example:
    Given a / b = 2.0, b / c = 3.0.
    queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
    return [6.0, 0.5, -1.0, 1.0, -1.0 ].
    
    The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector<double>.
    
    According to the example above:
    equations = [ ["a", "b"], ["b", "c"] ],
    values = [2.0, 3.0],
    queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 
    

      

    解法:并查集(Disjoint Set)

    根据给定的【被除数,除数,商】,可以建立【被除数,除数】之间的关系(系数为【商】)

    则所有【被除数,除数】对,可以看作两个顶点的连接。(【商】为两点连接的系数)

    最后所求为,给定两个点是否有连接,没有的话,返回-1,否则返回两点之间的系数【商】。

    因此,我们可在原来基础的Disjoint Set中parent的关系基础上,增加一个变量,来指示二点之间的关系系数【商】

    vector<pair<int, double>> parent;

    • parent[i].first:顶点 i 的父节点
    • parent[i].second:顶点 i 与其父节点的关系系数

    ->  顶点 i = parent[i] * 系数

    在本问题中,

    1. 由于顶点不确定性,我们不再使用固定长度的parent。而使用动态变化的parent。这里需要增加,增加节点方法:newpoint
    2. 顶点指示为string类型,因此需要增加映射,unordered_map<string, int> pos;

    综上,我们对本问题经过适用改善的Disjoint Set类变为:

     1 class DisjointSet {
     2 public:
     3     DisjointSet() {}
     4     void newpoint() {
     5         parent.push_back(make_pair(parent.size(), 1.0));
     6         rank.push_back(0);
     7     }
     8     pair<int, double> find(int i) {
     9         if(parent[i].first != i){
    10             pair<int, double> pa = find(parent[i].first);
    11             parent[i].first = pa.first;
    12             parent[i].second *= pa.second;
    13         }
    14         return parent[i];
    15     }
    16     bool merge(int x, int y, double val) {//x=y*val
    17         pair<int, double> x_root = find(x);
    18         pair<int, double> y_root = find(y);
    19         if(x_root.first == y_root.first) return false;
    20         if(rank[x_root.first] < rank[y_root.first]) {
    21             parent[x_root.first].first = y_root.first;
    22             parent[x_root.first].second = y_root.second * val;
    23         } else if(rank[y_root.first] < rank[x_root.first]) {
    24             parent[y_root.first].first = x_root.first;
    25             parent[y_root.first].second = x_root.second / val ;
    26         } else {
    27             parent[x_root.first].first = y_root.first;
    28             parent[x_root.first].second = y_root.second * val;
    29             rank[y_root.first] ++;
    30         }
    31         return true;
    32     }
    33     double getdivideval(int x, int y) {
    34         pair<int, double> x_root = find(x);
    35         pair<int, double> y_root = find(y);
    36         if(x_root.first == y_root.first) return x_root.second/y_root.second;
    37         else return -1.0;
    38     }
    39 private:
    40     vector<pair<int, double>> parent;
    41     vector<int> rank;
    42 };

    本问题的解决

    代码参考:

     1 class Solution {
     2 public:
     3     vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
     4         vector<double> res;
     5         unordered_map<string, int> pos;
     6         DisjointSet DS;
     7         for(int i=0; i<values.size(); i++) {
     8             string a = equations[i][0];
     9             string b = equations[i][1];
    10             double val = values[i];
    11             if(pos.count(a)==0) {
    12                 pos[a] = pos.size();
    13                 DS.newpoint();
    14             }
    15             if(pos.count(b)==0) {
    16                 pos[b] = pos.size();
    17                 DS.newpoint();
    18             }
    19             DS.merge(pos[a],pos[b],val);
    20         }
    21         for(vector<string> q:queries) {
    22             if(pos.count(q[0]) == 0 || pos.count(q[1]) == 0) {
    23                 res.push_back(-1.0);
    24             } else {
    25                 res.push_back(DS.getdivideval(pos[q[0]], pos[q[1]]));
    26             }
    27         }
    28         return res;
    29     }
    30 };
  • 相关阅读:
    【BZOJ4892】【TJOI2017】—DNA(后缀数组+ST表)
    【BZOJ1563】【NOI2009】—诗人小G(决策二分栈优化dp)
    【洛谷P5249】【LnOI2019】—加特林轮盘赌(概率dp)
    【Ural1519】— Formula1(轮廓线dp)
    【BZOJ3728】【PA2014】—Final Zarowki(思维题)
    【BZOJ3730】—震波(动态点分治)
    【Hackerrank (70)】—Range Modular Query(莫队+暴力)
    【省选模拟】—Cactus(圆方树+dfs序)
    【BZOJ2125】—最短路(圆方树+树链剖分)
    python 基础 列表
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13458379.html
Copyright © 2020-2023  润新知