题目链接如下:
一个很简洁的写法:UVa 12166 Equilibrium Mobile——思路题_equilibrium mobile uva - 12166-优快云博客
才33行,真的NB坏了……
我的比较繁琐的代码(能AC),比较之下就能发现,其实不用构建叶子节点的vec,找到一个叶子节点直接把它对应的平衡树算出来就可以了:
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <map>
// #define debug
struct node{
long long key;
int level;
node(long long _key, int _level): key(_key), level(_level){}
};
int T;
std::string ss;
std::vector<node> vec;
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
scanf("%d\n", &T);
while (T--){
getline(std::cin, ss);
vec.clear();
int level = 0;
for (int i = 0; i < ss.size(); ++i){
if (ss[i] == '['){
level++;
} else if (ss[i] == ']'){
level--;
} else if (ss[i] == ','){
continue;
} else {
vec.push_back(node((long long)std::atoi(ss.substr(i).c_str()), level));
while (isdigit(ss[i + 1])){
i++;
}
}
}
int nbr = 0;
std::map<long long, int> mp;
for (int i = 0; i < vec.size(); ++i){
mp[vec[i].key << vec[i].level]++;
}
for (auto it = mp.begin(); it != mp.end(); ++it){
if (it->second > nbr){
nbr = it->second;
}
}
printf("%d\n", vec.size() - nbr);
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
前面还写了两个严重超时的解法,还是贴在下面。
(记录自己的愚蠢。)
超时代码1:
#include <string>
#include <iostream>
#include <cstdlib>
#include <vector>
const int maxx = 99999999;
#define debug
struct node{
double key;
node* left = nullptr;
node* right = nullptr;
node* parent = nullptr;
};
int T, cnt;
std::string ss;
std::vector<node*> vec;
node* findRoot(std::string str){
if (isdigit(str[0])){
node* temp = new node;
temp->key = (double) std::atoi(str.c_str());
vec.push_back(temp);
return temp;
}
str = str.substr(1, str.size() - 2);
int nbr = 0;
int i;
for (i = 0; i < str.size(); ++i){
if (str[i] == ',' && nbr == 0){
break;
}
if (str[i] == '['){
nbr++;
} else if (str[i] == ']'){
nbr--;
}
}
node* temp = new node;
node* l = findRoot(str.substr(0, i));
l->parent = temp;
node* r = findRoot(str.substr(i + 1));
r->parent = temp;
temp->key = l->key + r->key;
temp->left = l;
temp->right = r;
return temp;
}
void balance(node* rt, double tot){
if (!rt->left && !rt->right){
if (rt->key != tot){
cnt++;
}
return;
}
balance(rt->left, tot / 2);
balance(rt->right, tot / 2);
}
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
scanf("%d\n", &T);
while (T--){
vec.clear();
getline(std::cin, ss);
node* root;
root = findRoot(ss);
int minn = maxx;
for (int i = 0; i < vec.size(); ++i){
node* temp = vec[i];
while (temp->parent){
temp->parent->key = temp->key * 2;
temp = temp->parent;
}
cnt = 0;
balance(temp, temp->key);
if (cnt < minn){
minn = cnt;
}
}
printf("%d\n", minn);
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
超时代码2:
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
const int maxx = 99999999;
#define debug
struct node{
long long key;
int level;
node(long long _key, int _level): key(_key), level(_level){}
};
int T;
std::string ss;
std::vector<node> vec;
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
scanf("%d\n", &T);
while (T--){
getline(std::cin, ss);
vec.clear();
int level = 0;
for (int i = 0; i < ss.size(); ++i){
if (ss[i] == '['){
level++;
} else if (ss[i] == ']'){
level--;
} else if (ss[i] == ','){
continue;
} else {
vec.push_back(node((long long)std::atoi(ss.substr(i).c_str()), level));
while (isdigit(ss[i + 1])){
i++;
}
}
}
int minn = maxx;
for (int i = 0; i < vec.size(); ++i){
int cnt = 0;
for (int j = 0; j < vec.size(); ++j){
if (vec[i].level <= vec[j].level){
if (vec[j].key << vec[j].level - vec[i].level != vec[i].key){
cnt++;
}
} else {
if (vec[i].key << vec[i].level - vec[j].level != vec[j].key){
cnt++;
}
}
}
if (cnt < minn){
minn = cnt;
}
}
printf("%d\n", minn);
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}