文远知行8月20日笔试
感觉是最近写的最难的题。。。
2个小时就三道编程题
第一题:
是设定两个针对0或1的计算操作(1)或运算(2)与运算,与运算的优先级比或高。
给定一个包含+,* ,(,)是个符号的字符串表示省略01的计算表达式,+代表或运算,*代表与运算。要求填充01,统计最后表达式计算值为0的个数。
思路: 这道题有点像加乘计算器,只不过因为要统计个数,所以数字应该是一个pair。 pair.first 代表0的个数,pair.second代表1的个数。然后利用双栈存储nums和ops。好久没写计算器这道题了,这个破题就写了1个小时。
第二题:
给定n个坐标点,求构成简单多边形的最大边长。
这道题我感觉的思路是先算出两点之间距离,然后再dfs遍历取边。比较重要的是判断是否为简单多边形,也就是两个线段是否相交。然后考场上写了一个函数来判断,主要是解一个二元方程组,当时是这样写的:
bool _isInteract(pair<double, double>& a, pair<double, double>& b, pair<double, double>& c, pair<double, double>& d) { double a11 = a.first - b.first; double a12 = -c.first + d.first; double a21 = a.second - b.second; double a22 = -c.second + d.second; double b1 = d.first - b.first; double b2 = d.second - b.second; double delta = a11 * a22 - a12 * a21; a11 = a22 / delta; a12 = a21 / delta; a21 = a12 / delta; a22 = a11 / delta; double x1 = a11 * b1 + a12 * b2, x2 = a21 * b1 + a22 * b2; return x1 > 0 && x1 < 1 && x2 > 0 && x2 < 1; }
然后整体上最后是这样的:
#include <climits> #include <iostream> #include <cmath> #include <vector> using namespace std; double final_res = 0; double temp_res = 0; vector<pair<int, int>> edges; int n; bool _isInteract(pair<double, double>& a, pair<double, double>& b, pair<double, double>& c, pair<double, double>& d) { double a11 = a.first - b.first; double a12 = -c.first + d.first; double a21 = a.second - b.second; double a22 = -c.second + d.second; double b1 = d.first - b.first; double b2 = d.second - b.second; double delta = a11 * a22 - a12 * a21; a11 = a22 / delta; a12 = a21 / delta; a21 = a12 / delta; a22 = a11 / delta; double x1 = a11 * b1 + a12 * b2, x2 = a21 * b1 + a22 * b2; return x1 > 0 && x1 < 1 && x2 > 0 && x2 < 1; } double dis(pair<double, double>& a, pair<double, double>& b) { double res = pow(a.first - b.first, 2) + pow(a.second - b.second, 2); return sqrt(res); } bool isInteract(vector<pair<double, double>>& nodes, pair<double, double>& c, pair<double, double>& d) { for (auto& edge : edges) { if (_isInteract(nodes[edge.first], nodes[edge.second], c, d)) return true; } return false; } bool _check(vector<int>& is_vis){ for(auto& iter: is_vis) if(iter != 2) return false; return true; } void dfs(vector<vector<bool>>& is_vis_edge, vector<pair<double, double>>& nodes, vector<vector<double>>& adj, vector<int>& is_vis) { if (edges.size() == n) { if(_check(is_vis)) final_res = max(final_res, temp_res); return; } for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) if (is_vis[i] < 2 && is_vis[j] < 2 && !is_vis_edge[i][j] && !isInteract(nodes, nodes[i], nodes[j])) { temp_res += adj[i][j]; ++is_vis[i]; ++is_vis[j]; is_vis_edge[i][j] = true; edges.emplace_back(i,j); dfs(is_vis_edge,nodes,adj,is_vis); temp_res -= adj[i][j]; --is_vis[i]; --is_vis[j]; is_vis_edge[i][j] = false; edges.pop_back(); } } int main() { cin >> n; if(n <= 1){ printf("%.2f",0.00); return 0; } vector<pair<double, double>> nodes(n, {0, 0}); vector<vector<double>> adj(n, vector<double>(n, 0)); for (int i = 0; i < n; ++i) cin >> nodes[i].first >> nodes[i].second; for (int i = 0; i < n; ++i) for (int j = i+1; j < n; ++j) adj[i][j] = dis(nodes[i], nodes[j]); vector<int> is_vis(n, 0); vector<vector<bool>> is_vis_edge(n, vector<bool>(n, false)); dfs(is_vis_edge,nodes,adj,is_vis); printf("%.2f",final_res); return 0; } // 64 位输出请用 printf("%lld")
这个代码样例可以过,然后提交只过15%,不知道为啥。。。
第三题甚至没来得及看,感觉寄了。
#文远知行##Weride#