7-12 h0188. 恼人的青蛙

在韩国,有一种小的青蛙。每到晚上,这种青蛙会跳越稻田,从而踩踏稻子。农民在早上看到被踩踏的稻子,希望找到造成最大损害的那只青蛙经过的路径。每只青蛙总是沿着一条直线跳越稻田,而且每次跳跃的距离都相同。


如下图所示,稻田里的稻子组成一个栅格,每棵稻子位于一个格点上。而青蛙总是从稻田的一侧跳进稻田,然后沿着某条直线穿越稻田,从另一侧跳出去


如下图所示,可能会有多只青蛙从稻田穿越。青蛙的每一跳都恰好踩在一棵水稻上,将这棵水稻拍倒。有些水稻可能被多只青蛙踩踏。当然,农民所见到的是图4中的情形,并看不到图3中的直线,也见不到别人家田里被踩踏的水稻。


根据图4,农民能够构造出青蛙穿越稻田时的行走路径,并且只关心那些在穿越稻田时至少踩踏了3棵水稻的青蛙。因此,每条青蛙行走路径上至少包括3棵被踩踏的水稻。而在一条青蛙行走路径的直线上,也可能会有些被踩踏的水稻不属于该行走路径
①不是一条行走路径:只有两棵被踩踏的水稻;
②是一条行走路径,但不包括(2,6)上的水道;
③不是一条行走路径:虽然有3棵被踩踏的水稻,但这三棵水稻之间的距离间隔不相等。

请你写一个程序,确定:在一条青蛙行走路径中,最多有多少颗水稻被踩踏。例如,图4的答案是7,因为第6行上全部水稻恰好构成一条青蛙行走路径。

输入格式:

从标准输入设备上读入数据。第一行上两个整数R、C,分别表示稻田中水稻的行数和列数,1≤R、C≤5000。第二行是一个整数N,表示被踩踏的水稻数量, 3≤N≤5000。在剩下的N行中,每行有两个整数,分别是一颗被踩踏水稻的行号(1~R)和列号(1~C),两个整数用一个空格隔开。而且,每棵被踩踏水稻只被列出一次。

输出格式:

从标准输出设备上输出一个整数。如果在稻田中存在青蛙行走路径,则输出包含最多水稻的青蛙行走路径中的水稻数量,否则输出0。

6 7
14 
2 1 
6 6 
4 2 
2 5 
2 6 
2 7 
3 4 
6 1 
6 2 
2 3 
6 3 
6 4 
6 5 
6 7 
 

输出样例:

 7

 

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

#include<stdio.h>
#include<math.h>

int lenth = 0;//被踩水稻数量
int pt[5000][3];//被踩水稻坐标position location
int r_max, c_max;//稻田的r,c值
int paddy_max = 0;//被踩水稻最大值
int map[5001][5001];//稻田地图

//输入
//将所有被踩水稻坐标存入pt[5000][3]
//稻田map中 被踩的水稻的值为 1,未被踩水稻值为 0
void Input(void)
{
	int j;
	int i;
	int r;
	int c;
	scanf("%d %d", &r_max, &c_max);
	//将稻田全部置0
	for (i = 0; i <= r_max; i++)
	{
		for (j = 0; j <= c_max; j++)
		{
			map[i][j] = 0;
		}
	}
	scanf("%d", &lenth);
	for (i = 0; i < lenth; i++)
	{
		scanf("%d %d", &r, &c);
		pt[i][0] = r;
		pt[i][1] = c;
		map[r][c] = 1;
	}
	//求出稻田中最长路径的值
}


//以index 为起点,dr,dc为增量求该路径上被踩水稻的数量,
//若这条路径的被踩水稻数量大于paddy_max,则更新paddy_max
//只判断dr和dc增加的情况,dr和dc减小的情况结果相同无需计算
int Max_finding(int index, int dr, int dc)
{

	int paddy_sum = 0;//这条路径上被踩水稻的数量
	//当前点位的坐标
	int now_r = pt[index][0];
	int now_c = pt[index][1];

	//若dr和dc均大于0则进行求paddy_sum
	if (dr < 0 || dc < 0 || (dr == 0 && dc == 0))
	{
		return paddy_sum;
	}

	while (now_r <= r_max && now_c <= c_max)//当前点位的坐标在稻田内
	{
		//若当前点位水稻被踩
		//跳到下一个点位
		//被踩水稻数量加一
		if (map[now_r][now_c] == 1)
		{
			now_r += dr;
			now_c += dc;
			paddy_sum++;
		}
		//当前点位水稻未被踩,但该点在稻田内
		//说明青蛙未从该条路径跳出稻田
		//说明该路径不是一条正确路径
		else
		{
			paddy_sum = 0;
			break;
		}
	}

	//判断是否更新paddy_max
	if (paddy_sum > paddy_max)
	{
		paddy_max = paddy_sum;
	}
	return paddy_max;
}



int main(void)
{
	int i;
	int j;
	int dr;//两点之间r的增量
	int dc;//两点之间c的增量
	int pre_r;//起点上一个点的r previous_r
	int pre_c;//起点上一个点的c previous_c

	//输入
	Input();


	for (i = 0; i < lenth; i++)//以点 i 为起点
	{
		for (j = 0; j < lenth; j++)//求 j 点与 i 点之间的dr dc ds
		{
			dr = pt[j][0] - pt[i][0];
			dc = pt[j][1] - pt[i][1];

			//如果起点上一个点在稻田内
			//说明该点为起点的路径上最多只有paddy_max-1个被踩水稻
			pre_r = pt[i][0] - dr;
			pre_c = pt[i][1] - dc;
			if ((pre_r >= 1 && pre_r <= r_max) && (pre_c >= 1 && pre_c <= c_max))
			{
				continue;
			}

			Max_finding(i, dr, dc);//dr,dc均为正值
		}
	}

		printf("%d", paddy_max);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值