题目地址
http://poj.org/problem?id=1054
题目大意
- 青蛙踩稻田里的水稻,青蛙只能直线跳,并且每一跳都相等
- 给出稻田里被踩倒得水稻,求青蛙中踩倒最多水稻的数目
解题思路
- 枚举,取出二个点,当做起始点
- 剪枝
Code
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <map>
#include <vector>
#include <math.h>
#include <algorithm>
#define INF 0x3fffffff
#define N 5100
using namespace std;
typedef long long LL;
int t;
int n, m;
bool vis[N][N];
struct Node {
int x, y;
bool operator < (const Node b) const {
if (x == b.x) {
return y < b.y;
} else {
return x < b.x;
}
}
};
Node area[N];
bool mfind(int x, int y) {
return vis[x][y];
}
int get_num(int ox, int oy, int dx, int dy) {
int ans = 0;
int nx = ox;
int ny = oy;
while (1 <= nx && nx <= n && 1 <= ny && ny <= m) {
if (mfind(nx, ny)) {
ans++;
} else {
ans = 0;
break;
}
nx += dx;
ny += dy;
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#else
//
#endif
cin >> n >> m;
cin >> t;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < t; i++) {
cin >> area[i].x >> area[i].y;
vis[area[i].x][area[i].y] = 1;
}
sort(area, area+t);
int ans = 0;
// area[i] : first point
// area[j] : second point
for (int i = 0; i < t-1; i++) {
for (int j = i+1; j < t; j++) {
int dx = area[j].x - area[i].x;
int dy = area[j].y - area[i].y;
int ox = area[i].x - dx;
int oy = area[i].y - dy;
// should be out of area
if (1 <= ox && ox <= n && 1 <= oy && oy <= m) continue;
// cut the unreachable
if (area[i].x + (ans-1) * dx > n) {
break;
}
ans = max(ans, get_num(area[i].x, area[i].y, dx, dy));
}
}
// at least is 3
if (ans == 2) ans = 0;
cout << ans << endl;
return 0;
}