中山大学算法课程题目详解(第五周)

来源:互联网 发布:我想学软件编程 编辑:程序博客网 时间:2024/06/07 05:51

问题描述:

Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

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"] ]. 

The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.

问题解决思路:

首先,主要到每个除法表达式都有个值,而且是双向的,可以用图的方法来解决,这里要特别注意图是无向图,例如等式a / b = 2.0,可以转化为两条边:<a, b>,<b, a>,其长度分别为2.0,0.5。先判断2个点是否都出现,然后判断是不是自己到自己,最后用dfs进行搜索,然后用递归进行每条边权重的相乘,如果最后找不到路径,则返回-1.0;这里采用嵌套map作为存储对应边的两个点以及权值,采用set存储在dfs中以及被访问的点。

具体实现代码:

class Solution {public:    double dfs(string from, string to, map<string, map<string, double>> &mp, set<string> & visited, double val){if (mp[from].count(to)) {return mp[from][to] * val;}for (pair<string, double>p : mp[from]) {string str = p.first;if (visited.count(str) == 0) {visited.insert(str);double cur = dfs(str, to, mp, visited, p.second * val);if (cur != -1.0) return cur;}}return -1.0;}vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {vector<double> result;map<string, map<string, double>> mp;int i = 0;for (pair<string, string> p : equations) {mp[p.first][p.second] = values[i];mp[p.second][p.first] = 1.0 / values[i];i++;}for (pair<string, string> p : queries) {if (mp.count(p.first) && mp.count(p.second)) {if (p.first == p.second) {result.push_back(1.0);continue;}else {set<string> visited;result.push_back(dfs(p.first, p.second, mp, visited, 1.0));}}else {result.push_back(-1.0);}}return result;}};