这道题又是一道递归的题目
先贴上代码
//这种没有明确说个数的动态分配还是得用new #include<cstdio> #include<iostream> using namespace std; struct mobile { int WL,DL,WR,DR; mobile *left,*right; mobile(mobile *a=NULL,mobile*b=NULL):left(a),right(b){} }; mobile *top =NULL; int kase; mobile* read_input() { mobile *u = new mobile; scanf("%d%d%d%d",&u->WL,&u->DL,&u->WR,&u->DR); //printf("%d %d %d %d \n",u->WL,u->DL,u->WR,u->DR); if(u->WL == 0) { u->left = read_input(); } if(u->WR == 0) { u->right = read_input(); } return u; } void clear(mobile* u) { if(u) { clear(u->left); clear(u->right); delete u; } } //又是一个递归 void compute(mobile* u,int &W,bool &flag) { //实际上这里应该有一个专门处理子节点的语句来结束递归,但是这个语句与下面的合并的语句可以和在一起判断。 if(u->WL&&u->WR) { W = u->WL + u->WR; if(u->DL*u->WL==u->DR*u->WR) { flag = true; } else flag = false; return; } bool left_flag = 1; bool right_flag = 1; if((u->left) && (u->WL == 0)) compute(u->left,u->WL,left_flag); if((u->right) && (u->WR == 0)) compute(u->right,u->WR,right_flag); W = u->WL + u->WR; if(u->DL * u->WL == u->DR*u->WR&&left_flag&&right_flag) { flag=true; } else flag=false; return ; } void print_mobile(mobile *u) { printf("\n"); printf("%d %d %d %d \n",u->WL,u->DL,u->WR,u->DR); if(u->left) print_mobile(u->left); if(u->right) print_mobile(u->right); printf("\n"); } int main() { #ifdef local freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif scanf("%d",&kase); for(int i = 0;i < kase;i++) { if(i) printf("\n"); clear(top); top = read_input(); //print_mobile(top); bool flag ; int weight; compute(top,weight,flag); //print_mobile(top); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
我的版本和刘汝佳版本有一点不一样,刘汝佳是直接在输入的时候就判断完毕了,而我是输入完之后又遍历一遍才输入完毕,在考场时倾向于后者,因为编程简单
第二点是刘汝佳的bool数据结构是使用返回值来返回的,而我的是使用引用来修改的,这两者在使用上没有本质上的区别
第三点,在我写的compute函数中,第一个部分处理叶节点的部分可以不要,因为可以后后面结合的部分合并起来,功能上是一样的。
还是得细细品味这种递归的思想啊