1. 程式人生 > >I - 天平 (p157,二叉樹的 DFS) UVA - 839

I - 天平 (p157,二叉樹的 DFS) UVA - 839

相等 namespace int scanf ldl %d 描述 div input

題目

輸入一個樹狀天平,根據力矩相等原則判斷是否平衡。如圖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\n"); else printf("NO\n"); if(T)pritnf("\n"); } 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("\n");
}

I - 天平 (p157,二叉樹的 DFS) UVA - 839