Not so Mobile
我的思路:可以将天平看做一棵二叉树,二叉树的每个节点要记录其父节点。然后其实就是一个建树的过程,遇到 0 节点就向下延伸,每当一个节点的左右子树确定(其重量也随之确定),就计算其是否平衡,然后一直向上追溯,直到该节点尚未平衡,继续建树,直至整棵树建好,是否平衡也随之确定。
version 1(40ms):
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 5;
int t,wl,dl,wr,dr;
struct node{
int w = 0,d = 0;
struct node* dad = NULL;
struct node* left = NULL;
struct node* right = NULL;
};
node* newnode(){ return new node; }
void build_tree(int& mark){
node* root = newnode();
node* t = root;
while(!root->w){
scanf("%d%d%d%d",&wl,&dl,&wr,&dr);
if(!t->left){
t->left = newnode();
t->left->w = wl;
t->left->d = dl;
t->left->dad = t;
}
if(!t->right){
t->right = newnode();
t->right->w = wr;
t->right->d = dr;
t->right->dad = t;
}
if(t->left->w && t->right->w){
while(t->left->w && t->right->w){
t->w = t->left->w + t->right->w;
if(mark && t->left->w*t->left->d != t->right->w*t->right->d) mark = 0;
if(t == root) break;
t = t->dad;
}
t = (!t->left->w ? t->left : t->right);
}
else if(!t->left->w) t = t->left;
else t = t->right;
}
}
int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
scanf("%d",&t);
while(t--){
int mark = 1;
build_tree(mark);
printf("%s\n",mark ? "YES" : "NO");
if(t) putchar('\n');
}
return 0;
}
看了看书上的代码,直接递归就行。。。既简洁又优美。智商的差距。。。
version 2(20ms):
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 5;
int t,w;
bool solve(int& w){
int wl,dl,wr,dr;
scanf("%d%d%d%d",&wl,&dl,&wr,&dr);
int bl = 1,br = 1;
if(!wl) bl = solve(wl);
if(!wr) br = solve(wr);
w = wl + wr;
return bl && br && wl*dl == wr*dr;
}
int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
scanf("%d",&t);
while(t--){
printf("%s\n",solve(w) ? "YES" : "NO");
if(t) putchar('\n');
}
return 0;
}