此题关键是将所有点排序后,遍历每次确保被选中的两个点是一条青蛙路径上最先被踩踏的两个水稻。
在遍历点的过程中,要注意青蛙能够从一侧进入稻田,沿着直线一直跳,直到最后跳出稻田,如果青蛙连着跳了4个点,该条直线上的第5点还在稻田中,但是青蛙没有踩踏,则该条路径不合法,不能记录青蛙当前最大的踩踏数是4,而应该记0。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
bool vis[5005][5005]; //记录对应坐标是否被踩过, int型竟然TLE
struct Point{
int x;
int y;
}p[5005];
bool cmp(Point a,Point b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int R,C,n;
scanf("%d%d",&R,&C);
scanf("%d",&n);
int a,b;
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
p[i].x=a;
p[i].y=b;
vis[a][b]=true;
}
sort(p,p+n,cmp);
int maxn=2; //当前踩过的水稻的最大数目
for(int i=0;i<n-2;i++)
{
for(int j=i+1;j<n-1;j++)
{
int dx=p[j].x-p[i].x;
int dy=p[j].y-p[i].y;
int x0=p[i].x-dx;
int y0=p[i].y-dy;
int x3=p[j].x+dx;
int y3=p[j].y+dy;
//保证i,j是最先被踩踏的两个水稻
if(x0>=1 && x0<=R && y0>=1 && y0<=C)
continue;
if(x3<1 || x3>R || y3<1 || y3>C) continue;
if(!vis[x3][y3]) //无法构成一条三个踩踏点
continue;
int sum=2;
//最后的出口一定是点不在范围了,即青蛙一直走到尽头跳出
while(x3>=1 && x3<=R && y3>=1 && y3<=C)
{
if(vis[x3][y3])
sum++;
else {sum=0; break;} //青蛙走这条路没有跳出池塘,WA点
x3+=dx;
y3+=dy;
}
if(sum>maxn) maxn=sum;
}
}
if(maxn==2) printf("0\n");
else printf("%d\n",maxn);
return 0;
}