4
Max(x,y) 7 20 55 1000 200 60 5000 1000 5000 3000
图片弄不上来几个意思?
随便扔张样例好了。。。
很显然一条蛙径上的点是在同一直线上,所以它们具有同一斜率(废话!)
那么如果(假设)能枚举所有斜率,然后再对点的距离处理下(呵呵)就能得出答案啦!
不过斜率是有无数种的,好一点的就是枚举平面任两点,然后再把这条直线扩出去(真难!)
不过注意到虽然最多有5000*5000个点,但是青蛙跳过的只有5000个点,所以枚举蛙点就行了!
既然确定斜率,还需知道一条线上有几个点,
首先将所有点按从左往右,从下到上排序,保证前面的点一定在后面的点左/下方
然后f[i][j] = (j,i)确定的斜率上1...i有多少点
设j关于i的对称点为k1,i关于j对称的点为k2
那么 f[i][j] = f[j][k] + 1(如果存在k1)
f[i][j] = 2(如果k1飞出去了)
f[i][j] = 0
注意!!!!!
自己实现的时候特别傻逼。。。
首先,一定先判断点是否出界,不然拿着出界的东西来搞会出事情!
然后,f[i][j] = 0并不好,假如你有三个点k,i,j满足蛙径定义,但你不一定保证k前面还有点
所以第三个方程应作f[i][j] = -INF
然后short站的内存是int的1/2(MLE?!)
#include
#include
#include
#include
using namespace std;
const int maxn = 5e3 + 10;
struct P{
int x,y;
bool operator < (const P &b) const {
if (y < b.y) return 1;
if (y > b.y) return 0;
return x > b.x;
}
}p[maxn];
short f[maxn][maxn],n,i,j,mx,my;
short s[maxn][maxn];
P dc(P a,P b) {return (P){a.x - (b.x - a.x),a.y - (b.y - a.y)};}
int main()
{
#ifndef YZY
freopen("frog.in","r",stdin);
freopen("frog.out","w",stdout);
#else
freopen("yzy.txt","r",stdin);
#endif
cin >> mx >> my >> n;
memset(s,0,sizeof(s));
for (i = 1; i <= n; i++) scanf("%d%d",&p[i].x,&p[i].y);
sort (p + 1,p + n + 1);
for (i = 1; i <= n; i++) s[p[i].x][p[i].y] = i;
for (i = 1; i <= n; i++)
for (j = 1; j < i; j++) {
P k = dc(p[j],p[i]);
if (k.x < 1 || k.y < 1 || k.x > mx || k.y > my) f[i][j] = 2;
else if (s[k.x][k.y] > 0) f[i][j] = f[j][s[k.x][k.y]] + 1;
else f[i][j] = -30000;
}
short ans = 0;
for (i = 1; i <= n; i++)
for (j = 1; j < i; j++) {
P k = dc(p[i],p[j]);
if ((k.x > mx || k.y > my || k.x < 1 || k.y < 1) && f[i][j] >= 3) ans = max(ans,f[i][j]);
}
cout << ans;
return 0;
}