I - 天平 (p157,二叉树的 DFS) UVA - 839
题目
输入一个树状天平,根据力矩相等原则判断是否平衡。如图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");
}