POJ 1054 The Troublesome Frog(枚举 + 剪枝)
题意:
http://blog.csdn.net/politropix/article/details/8456551
思路:
1. 首先针对 x 从小到大排序,然后枚举,这样为后面的剪枝提供了方便;
2. 对于剪枝,因为题目中明确说了:青蛙是从外面跳进来,至少踩了 3 个黑点,然后跳出去的,于是可以加下面剪枝:
a. 确定 2 点之间的间距之后,确定出发点之前的那个点是否在稻田外面,如果不是则剪枝;
b. 根据当前最优情况,确定当前的点只要要走多少步才能找到一个更优解,相当于是一个启发式的剪枝;
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 5010;
bool G[MAXN][MAXN];
struct POINT {
int x, y;
bool operator < (const POINT& other) {
if (x == other.x)
return y < other.y;
return x < other.x;
}
} P[MAXN];
int row, col, N;
bool judge(int x, int y) {
if (0 < x && x <= row && 0 < y && y <= col) {
return true;
}
return false;
}
int workout() {
int ans = 2;
for (int i = 0; i < N-1; i++) {
for (int j = i+1; j < N; j++) {
int dx = P[j].x - P[i].x;
int dy = P[j].y - P[i].y;
if (P[j].x + (ans-2)*dx > row)
break;
if (P[j].y + (ans-2)*dy > col || P[j].y + (ans-2)*dy < 1)
continue;
if (judge(P[i].x-dx, P[i].y-dy))
continue;
int t = 1;
int x = P[j].x, y = P[j].y;
while (judge(x, y) && G[x][y]) {
x += dx, y += dy, t += 1;
}
if (!judge(x+dx, y+dy))
ans = max(ans, t);
}
}
return ans > 2 ? ans : 0;
}
int main() {
while (~scanf("%d%d", &row, &col)) {
scanf("%d", &N);
memset(G, false, sizeof(G));
for (int i = 0; i < N; i++) {
scanf("%d%d", &P[i].x, &P[i].y);
G[P[i].x][P[i].y] = true;
}
sort(P, P + N);
printf("%d\n", workout());
}
return 0;
}
-------------------------------------------------------
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------