乐学C语言练习题:判断能否到达终点

题目描述:

对于任意一点(x, y),假设只有两种移动方式:(x, y) ->(x, x + y) ,(x, y) -> (x + y, y)。给定起点坐标(x1, y1),判断是否可以只通过上述移动方式到达终点坐标(x2, y2)。例如起点坐标为 (2, 10),终点坐标为(26, 12),

则 (2, 10)->(2, 12)->(14, 12)->(26, 12) 是有效的移动方式,可以从起点到达终点。

提示:判断能否从(x1,y1)通过限定的两种移动方式移动到(x2,y2),可以转化为判断能否从(x1,x1+y1)通过限定的两种移动方式移动到(x2,y2)以及能否从(x1+y1,y1)通过限定的两种移动方式移动到(x2,y2)。

输入: 

第一行为起点坐标,第二行为终点坐标。

输出:

如果可以通过上述移动方式到达终点,输出Yes.,否则输出No.

样例输入:

2, 10

26, 12

样例输出:

Yes.

解题思路:

寻找路径问题是一个典型的可以用递归解决的问题,但是这道题的难点在于如何去写出那个递归表达式。

不过,题目已经非常热心地给出了递归的思路,在递归时只需要返回对f(x+y,y)和f(x,x+y)这两个点是否能到达终点问题的判断即可。

下面开始递归:

首先考虑什么是递归的出口?我们把从起点出发的点看成一个动点,由于题目给出的所有坐标都是正数,所以我们可以自然看出,动点是无法往回走的,即该点运动之后的横纵坐标不可能比原来的坐标值还小,所以当这个动点的横纵坐标之一大于终点的横纵坐标时,我们就可以判断他不可能再到达终点了。而自然,当他横纵坐标都等于终点时,我们才可以输出1,即其到达了终点。

接下来,考虑如何实现返回值。我们当然可以使用逻辑运算符&&实现,不过写到这里的时候你是否想起了大学计算机课程中的二进制两位加法器 : ( ,所以可以直接用两个函数值的加法,如果其中有一个的值不等于零,输出就不为零,这个方法需要注意的是,判断为真时函数不一定只输出1,而可能是2,3,4,5......所以后面的主函数中我们不能写find(...)==1。

总的代码还是非常简单的,最主要的还是想出递归算法

#include<stdio.h>

int find(int x1,int y1,int x2,int y2)
{
	if(x1==x2&&y1==y2) return 1;
	else if(x1>x2||y1>y2) return 0;
	else return find(x1+y1,y1,x2,y2)+find(x1,x1+y1,x2,y2);
}

int main()
{
	int x1,y1,x2,y2;
	scanf("%d,%d%d,%d",&x1,&y1,&x2,&y2);
	if(find(x1,y1,x2,y2)) printf("Yes.\n");
	else printf("No.\n");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值