在韩国,有一种小的青蛙。每到晚上,这种青蛙会跳越稻田,从而踩踏稻子。农民在早上看到被踩踏的稻子,希望找到造成最大损害的那只青蛙经过的路径。每只青蛙总是沿着一条直线跳越稻田,而且每次跳跃的距离都相同。
如下图所示,稻田里的稻子组成一个栅格,每棵稻子位于一个格点上。而青蛙总是从稻田的一侧跳进稻田,然后沿着某条直线穿越稻田,从另一侧跳出去
如下图所示,可能会有多只青蛙从稻田穿越。青蛙的每一跳都恰好踩在一棵水稻上,将这棵水稻拍倒。有些水稻可能被多只青蛙踩踏。当然,农民所见到的是图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;
}