1.题目描述:点击打开链接
2.解题思路:本题利用dfs解决,不过思维上要发挥一些创造性。本题问至少要修改的砝码个数,那么首先可以想到要选一个基准砝码,其他所有的砝码都试图根据这个基准法吗而改变。不过本题的巧妙之处就在这里,只要以深度为depth(depth从0开始)重量为w的砝码为基准,那么就能求出整个天平的总重量,即w*2^(depth),在代码中可以简洁地表示为w<<depth。这样,我们只用统计每个可能的总重量对应了多少不需要改动的砝码,设一共有sum个砝码,总重量为sumw的天平对应的砝码个数是base[sumw],那么最终答案就是sum-max{base[i]}(i为所有可能的天平总重量)。本题在统计之前需要用dfs后序遍历该表达式。
本题的解法有点类似于找每个元素的某个贡献值的大小(在本题中贡献值就是以它为基准算出的天平总重量),同时统计该贡献值下元素有几个,那么最后取最优值即可。这种思维也是竞赛中的常见思维,应予以重视。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; string line; typedef long long LL; map<LL, int>base;//统计重量为sumw的天平对应的砝码个数 int sum; void dfs(int depth, int s, int e) { if (line[s] == '[') { int p = 0; for (int i = s + 1; i != e; i++) { if (line[i] == '[')p++; if (line[i] == ']')p--; if (!p&&line[i] == ',') { dfs(depth + 1, s + 1, i - 1);//后序遍历表达式,直到找到砝码 dfs(depth + 1, i + 1, e - 1); } } } else { LL w = 0; for (int i = s; i <= e; i++) w = w * 10 + line[i] - '0'; ++sum, ++base[w << depth];//sum统计砝码总数量,base[w<<depth]统计该总重量对应的砝码个数 } } int main() { freopen("t.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { cin >> line; base.clear(); sum = 0; dfs(0, 0, line.size() - 1); int maxn = 0; for (auto it = base.begin(); it != base.end(); it++)//利用C++ 11的新关键字auto自动识别类型 maxn = max(maxn, it->second); cout << sum - maxn << endl; } return 0; }
原文地址:http://blog.csdn.net/u014800748/article/details/44806749