uva 839 Not so Mobile 天平问题

这道题可以说是博主认为在树的DFS方面最为经典的一题了,思路巧妙细节满满啊。

  输入一个树状天平,根据力矩相等原则判断是否平衡,所谓力矩相等,就是w1r1=w2r2,w为天平左右两端砝码的重量,r为距离。采用递归(先序)的方式输入:每个天平的格式为w1,r1,w2,r2。当w1或w2为零时,表示该砝码实际上是一个子天平,接下来会描述这个子天平,当w1=w2=0时,会先描述左子天平,再描述右子天平。

Sample Input
1
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
S Sample Output
YES

哦对了要先输入一个数字n,n表示天平的个数,还有就是,每两个输出数据之间要用一个空行隔开(是空行!!)博主最讨厌格式这种套路了qwq。。。

不用想先序递归肯定是用DFS做喽,由于数据是按照我们需要的顺序给出的,所以这个题的巧妙处理方式之一就是一边输入一边做题,而不是从前那样先将输入存储起来再做题。

思路大体是这样子,天平怎样才能平衡呢?,需满足以下三个条件

1.若左边是子天平,则左子天平需平衡,是砝码则忽略该条件。

2.若右边是子天平,则右子天平需平衡,是砝码则忽略该条件。

3.该天平需平衡,即w1*r1==w2*r2 。

当我们进行到子天平时,怎样判断这个子天平是否平衡呢?我们需要进去看看才行,当然,要把是否平衡作为结果带回哦。

分析到这里代码就很好写了:

#include<cstdio>
using namespace std;
bool dfs(int &w)
{
    int w1,r1,w2,r2;
    bool flag1=true,flag2=true;
    scanf("%d%d%d%d",&w1,&r1,&w2,&r2);    //边递归边输入,一般只有给出的数据是先序才能这么干
     if(w1==0)
     flag1=dfs(w1);
     if(w2==0)
     flag2=dfs(w2);
     w=w1+w2;
     return flag1&&flag2&&(w1*r1==w2*r2);      //此处判断了上述的三个条件是否满足
}
int main()
{
 int n;
 int w;
 scanf("%d",&n);
 for(int i=0;i<n;i++)
 {
   if(i!=0)
    printf("\n");                   //解决了垃圾的格式问题
   if(dfs(w))                        //w用来带回天平的重量
   printf("YES\n");
   else
   printf("NO\n");
 }
 return 0;
}

博主做这道题时还犯了一个错误,就是没给flag1和flag2赋初值,卡了半个多小时,最后看了答案还很倔觉得不用赋。。。后来明白了显然是要赋的,当天平一端为砝码是我们应默认这个砝码自身是平衡的,不赋这个值的话砝码的flag就成了随机值了,还真不是人家uva判的严。。。想想当时真是太菜了,不知道有没有和我犯一样错误的小伙伴呢?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值