题意:稻田里的青蛙沿直线跳跃,每一只青蛙的跳长一定,现在发现稻田里有许多青蛙跳过的痕迹,根据这些痕迹求跳跃次数最多的那一条路线。
题解:注意题目的要求,首先要保证青蛙能从边界跳到所求路径的的开始位置,然后跳跃次数少于3的不算。一条直线上的点可以是不同青蛙跳跃的痕迹。
先排序,然后枚举开始的两个点,其实也就相当于枚举斜率,然后计算每一条斜率上最多的跳跃次数。
#include <algorithm> #include<iostream> using namespace std; #define N 5001 int R, C; bool map[N][N]; struct Point { int r, c; } node[N]; bool cmp ( Point & a, Point & b ) { if ( a.c == b.c ) return a.r < b.r; return a.c < b.c; } int solve ( int dr, int dc, int sr, int sc ) { int step = 2; int r = sr + dr, c = sc + dc; while ( r <= R && r >= 1 && c <= C ) { if ( map[r][c] == false ) return 0; step++; r += dr; c += dc; } return step; } int main() { int n, i, j, temp, ans; int dr, dc, rr, cc; memset(map,0,sizeof(map)); scanf("%d%d%d", &R, &C, &n ); for ( i = 1; i <= n; i++ ) { scanf("%d %d",&node[i].r,&node[i].c); map[node[i].r][node[i].c] = true; } sort ( node+1, node + 1 + n, cmp ); ans = 2; for ( i = 1; i < n; i++ ) { for ( j = i + 1; j <= n; j++ ) { dr = node[j].r - node[i].r; dc = node[j].c - node[i].c; rr = node[i].r - dr; cc = node[i].c - dc; if ( node[i].c + ans * dc > C ) break; if ( cc >= 1 && cc <= C && rr >= 1 && rr <= R ) continue; if ( node[i].r + ans * dr > R || node[i].r + ans * dr < 1 ) continue; temp = solve ( dr, dc, node[j].r, node[j].c ); if ( temp > ans ) ans = temp; } } printf ("%d\n", ans == 2 ? 0 : ans); return 0; }