POJ 1054 The Troublesome Frog 枚举

这个题分类是dp,想了一会没有想出来,就去看别人题解了。发现别人题解全是暴力枚举= =。复杂度超过 N^2,但可能是剪枝的作用,没有超时。

思路:将所有点按坐标由小到大排序。两两枚举点p1,p2,并判断其中坐标较小的点p1是否是该路径上青蛙跳至的第一个点(假设在p1之前还有一点,则可以根据p1和p2的距离算出p1前一点的坐标,判断该坐标是否在麦田内,若不在则说明p1是青蛙跳至的第一个点)。判定p1前一点坐标时,我原以为由于所有点的坐标都是排好序的(从小到大),则p1前一点的坐标必然更小,因此判定它是否在麦田内时只需要判断是否坐标都大于0,并不需要判断是否超坐标上限。但这种思路是错误的。见下图。

POJ 1054 The Troublesome Frog 枚举

上图情况中,排好序后两两枚举,则到点2与点3时,p1是点2,p2是点1,则p1的前一点在图中的虚线上,此时明显需要判断该点是否超过麦田的坐标上限。

通过上述判断规则,如果p1不是青蛙跳至的第一个点,则跳过该次枚举(因为它必然包含在某次枚举的情况里)。如果是,则根据p1到p2的坐标变化,判断p2后面所有要跳至的点是否都存在。如果存在,则该次枚举是有效的。记录该路径跳的次数。

最后求所有次数的最大值即可。

下面是代码:

 1 #include<stdio.h>

 2 #include<iostream>

 3 #include<string.h>

 4 #include<algorithm>

 5 #define maxn 5005

 6 using namespace std;

 7 struct nod

 8 {

 9     int x, y;

10     bool operator < (const nod &cmp) const

11     {

12         if (x == cmp.x) return y < cmp.y;

13         return x < cmp.x;

14     }

15 }rice[maxn];

16 bool map[maxn][maxn];

17 int main()

18 {

19     int r, c, n;

20     //freopen("data.in", "r", stdin);

21     scanf("%d%d%d",&r,&c,&n);

22     memset(map, 0, sizeof(map));

23     for (int i = 0; i < n; i++)

24     {

25         scanf("%d%d",&rice[i].x, &rice[i].y);

26         map[rice[i].x][rice[i].y] = 1;

27     }

28     sort(rice, rice + n);

29     int res = 0;

30     for (int i = 0; i < n; i++)

31         for (int j = i + 1; j < n; j++) if (i != j)

32         {

33             int dx = rice[j].x - rice[i].x;

34             int dy = rice[j].y - rice[i].y;

35             if (rice[i].x - dx >= 1 && rice[i].x - dx <= r && rice[i].y - dy >= 1 && rice[i].y - dy <= c) continue;

36             int nx = rice[j].x + dx;

37             int ny = rice[j].y + dy;

38             int len = 2;

39             int ok = 1;

40             while (nx > 0 && nx <= r && ny > 0 && ny <= c && ok)

41             {

42                 if (map[nx][ny]) len++;

43                 else ok = 0;

44                 nx += dx;

45                 ny += dy;

46             }

47             if (ok && len > 2) res = max(res, len);

48         }

49     printf("%d", res);

50     return 0;

51 }

 

 

你可能感兴趣的:(poj)