很基础的一道题,用了分治法建树,dfs求最值。
改进后代码真的简洁。。。
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define LL long long
#define maxn 10005
#define maxm 100005
#define mod 10007
#define INF 1e16+5
#define EPS 1e-7
#define PI 3.1415926535898
#define N 4294967296
using namespace std;
//-------------------------CHC------------------------------//
struct Node {
int val;
Node *left, *right;
Node () : left(NULL), right(NULL) { }
};
int in[maxn], pre[maxn], post[maxn], idx;
int minval, minsum, sum;
void GetPre(int pos, int l1, int r1, int l2, int r2) {
pre[pos] = post[r2 - 1];
int root = find(in + l1, in + r1, pre[pos]) - in;
int left = root - l1;
if (left >= 1) GetPre(pos + 1, l1, root, l2, l2 + left);
if (r1 - root - 1 >= 1) GetPre(pos + 1 + left, root + 1, r1, l2 + left, r2 - 1);
}
void build(Node *root, int l1, int r1, int l2, int r2) {
root->val = post[r2 - 1];
//printf("val = %d\n", root->val);
int mid = find(in + l1, in + r1, root->val) - in;
int left = mid - l1, right = r1 - mid - 1;
if (left >= 1) {
root->left = new Node();
build(root->left, l1, mid, l2, l2 + left);
}
if (right >= 1) {
root->right = new Node();
build(root->right, mid + 1, r1, l2 + left, r2 - 1);
}
}
void solve(Node *root) {
sum += root->val;
if (root->left) solve(root->left);
if (root->right) solve(root->right);
if (!root->right && !root->left)
if(!minval || sum < minsum) minsum = sum, minval = root->val;
sum -= root->val;
}
int main() {
#ifdef _DEBUG
IN(); OUT();
#endif
string read1, read2;
while (getline(cin, read1) && getline(cin, read2)) {
stringstream s1(read1), s2(read2);
idx = 0;
while (s1 >> in[idx] && s2 >> post[idx++]);
//GetPre(0, 0, idx, 0, idx);
//for (int i = 0; i < idx; ++i) printf("%d ", pre[i]); puts("");
Node *root = new Node();
build(root, 0, idx, 0, idx);
sum = minsum = minval = 0;
solve(root);
cout << minval << endl;
}
return 0;
}
两点改进,sum可以作为形参来达到相同的效果,可以直接用val作为地址建树。
改进后代码真的简洁。。。
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define LL long long
#define maxn 10005
#define maxm 100005
#define mod 10007
#define INF 1e16+5
#define EPS 1e-7
#define PI 3.1415926535898
#define N 4294967296
using namespace std;
//-------------------------CHC------------------------------//
int in[maxn], post[maxn], lch[maxn], rch[maxn], idx;
int minval, minsum, sum;
int build(int l1, int r1, int l2, int r2) {
int root = post[r2 - 1];
int mid = find(in + l1, in + r1, root) - in;
int left = mid - l1, right = r1 - mid - 1;
if (left >= 1) lch[root] = build(l1, mid, l2, l2 + left);
if (right >= 1) rch[root] = build(mid + 1, r1, l2 + left, r2 - 1);
return root;
}
void BFS(int root, int sum) {
sum += root;
if (lch[root]) BFS(lch[root], sum);
if (rch[root]) BFS(rch[root], sum);
if (!lch[root] && !rch[root])
if(!minval || sum < minsum) minsum = sum, minval = root;
}
int main() {
#ifdef _DEBUG
IN(); OUT();
#endif
string in_order, post_order;
while (getline(cin, in_order) && getline(cin, post_order)) {
CLEAR(lch, 0); CLEAR(rch, 0);
stringstream s1(in_order), s2(post_order);
idx = 0;
while (s1 >> in[idx] && s2 >> post[idx++]);
int root = build(0, idx, 0, idx);
sum = minsum = minval = 0;
BFS(root, 0);
cout << minval << endl;
}
return 0;
}