I

题目

输入一个树状天平,根据力矩相等原则判断是否平衡。如图6-5所示,所谓力矩相等,就是WlDl=WrDr,其中Wl和Wr分别为左右两边砝码的重量,D为距离。采用递归(先序)方式输入:每个天平的格式为Wl,Dl,Wr,Dr,当Wl或Wr为0时,表示该“砝码”实际是一个子天平,接下来会描述这个子天平。当Wl=Wr=0时,会先描述左子天平,然后是右子天平。

样例输入:

1
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2

输出
YES

我还是按照上一节数组记录结点的方法做,用递归dfs

#include<cstdio>

using namespace std;
const int maxn=100000+10;
int cnt=0;
int lft[maxn],rht[maxn],m[maxn],l_lft[maxn],l_rht[maxn],m_lft[maxn],m_rht[maxn];


int input (){
    cnt++;
    int root=cnt,lm,rm;
    scanf("%d%d%d%d",&lm,&l_lft[root],&rm,&l_rht[root]);
    if(lm==0){lft[root]=input(); lm=m[lft[root]];}
    else lft[root]=0;
    if(rm==0){rht[root]=input(); rm=m[rht[root]];}
    else rht[root]=0;
    m_lft[root]=lm;
    m_rht[root]=rm;
    m[root]=lm+rm;
    //printf("m_left [%d]=%d ",root,m_lft[root]=lm);
    //printf("m_right [%d]=%d ",root,m_rht[root]=rm);
    //printf("m[%d]=%d",root,m[root]=lm+rm);
    return root; 
}

bool dfs(int root){
    bool yes=false;
    if(l_lft[root]*m_lft[root]==l_rht[root]*m_rht[root]){
    if(lft[root]) if(!dfs(lft[root]))return yes;
    if(rht[root]) if(!dfs(rht[root]))return yes;
    yes= true;
    }
    return yes;
}

int main(){
    int T; scanf("%d",&T);
    while(T--){                      
        cnt=0; input();
        if(dfs(1)) printf("YES
");
        else printf("NO
");
        if(T)pritnf("
");
    }
    return 0;
}

书上:

如果树的输入过程采用递归输入,则中就能完成递归判断,利用引用传值,可以非常精简。

本题如是

//lrj的精简版本
#include<iostream>

using namespace std;

bool solve(int &M){
    int m1,m2,l1,l2;
    bool b1=true,b2=true;
    cin>>m1>>l1>>m2>>l2;
    if(!m1)b1=solve(m1);
    if(!m2)b2=solve(m2);
    M=m1+m2;
    return b1&&b2&&(m1*l1==m2*l2);
}

int main(){
    int M,T;
    cin>>T;
    while(T--){
      if(solve(M))cout<<"YES"<<endl;
      else cout<<"NO"<<endl;
      if(T) cout<<endl;
    }
    return 0;
} 

非常精简;

注: · 两组数据用空行隔开,最后一组后没有空行

所以:

while(T--){
if (T) cout<<endl;
if (T) printf("
");
}
原文地址:https://www.cnblogs.com/-ifrush/p/10201856.html