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<iostream> #include<cstdio> #include<algorithm> #include<cstring> 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; }