刚开始想的是用结构体数组解决这个问题,天平类似于二叉树,若天平根节点为k,则天平左边为根节点2k,右边为2k+1,这样的话当子天平递归完,return到父天平的时候方便判断是父节点的左子天平还是右子天平,然后将子天平的重量加到父天平上对父天平判断即可。很明显是个递归过程,代码如下
#include<iostream>
//#define LOCAL
using namespace std;
struct NODE {
int wl,dl,wr,dr;
bool flag=true;
//NODE(int wl=0,int dl=0,int wr=0,int dr=0,bool flag=true){};
} node[100010];
void read(int root) {
cin>>node[root].wl>>node[root].dl>>node[root].wr>>node[root].dr;
if(node[root].wl==0) {
read(2*root);
}
if(node[root].wr==0) {
read(2*root+1);
}
if(node[root].wl*node[root].dl!=node[root].wr*node[root].dr) {
//cout<<"NO"<<endl;
node[1].flag=false;
} else {
if(!(root%2))
node[root/2].wl+=node[root].wl+node[root].wr;
else {
node[root/2].wr+=node[root].wl+node[root].wr;
}
}
}
int n;
int main() {
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
cin>>n;
for(int i=0; i<n; i++) {
for(int j=0; j<100010; j++) {
node[j].wl=node[j].wr=node[j].dl=node[j].dr=0;
node[j].flag=true;
}
read(1);
if(i)
cout<<endl;
if(node[1].flag) {
cout<<"YES"<<endl;
} else
cout<<"NO"<<endl;
}
return 0;
}
不过这个爆RE了,本题没说明n的范围,所以我觉得可能是因为数组开的不够大吧,导致数组访问越界了,不过尝试过将节点数组开到10^6,仍然是RE,感觉再开大要爆内存了呃呃没办法了只能换方法了。
看了下书,想了下觉得确实没必要开结构体存储节点信息,边输入便判断不就行了吗。然后写了如下代码AC了。
#include<iostream>
using namespace std;
bool solve(int &w) {//传值引用
int wl,dl,wr,dr;
bool a=true,b=true,flag=false;
cin>>wl>>dl>>wr>>dr;
if(!wl)
a=solve(wl);
if(!wr)
b=solve(wr);
w=wl+wr;
if(wl*dl==wr*dr)
flag=true;
return a&&b&&flag;
}
int main() {
int n;
cin>>n;
for(int i=0; i<n; i++) {
if(i)
cout<<endl;
int w=0;
if(solve(w)) {
cout<<"YES"<<endl;
} else {
cout<<"NO"<<endl;
}
}
return 0;
}
对了注意一下格式。