【POJ】1054 The Troublesome Frog

题目是非常经典的搜索+剪枝。题意简言之就是,青蛙需要沿着直线踩着踏点通过田地,并且踏点需要至少为3。问哪条路径青蛙踩坏的作物最多。很好的一个条件是青蛙每次移动都是等间距的。题目需要注意将其排序。

#include <iostream>
using namespace std;

#define MAXNUM 5005

typedef struct {
    int x, y;
} point_st;

point_st points[MAXNUM];
bool Fields[MAXNUM][MAXNUM];
int r, c, n;

int comp(const void *a, const void *b) {
    point_st *p1 = (point_st *)a;
    point_st *p2 = (point_st *)b;
    if (p1->x != p2->x)
        return p1->x - p2->x;
    else
        return p1->y - p2->y;
}

int calPath(int p1, int p2) {
    int x1 = points[p1].x, y1 = points[p1].y;
    int x2 = points[p2].x, y2 = points[p2].y;
    int nx, ny, cnt = 2;

    while (1) {
        nx = 2*x2 - x1;
        ny = 2*y2 - y1;
        if (nx>0 && nx<=r && ny>0 && ny<=c) { // 保持在田地范围内
            if (Fields[nx][ny]) {
                cnt++;
                x1 = x2; y1 = y2;
                x2 = nx; y2 = ny;
            } else {
                return 0;  // 前面没有踏点了,即此路不通
            }
        } else {
            if (cnt >= 3)
                return cnt; 
            else
                return 0;  // 踏点不足3,不符合题意
        }
    }
}

int main() {
    int i, j, k;
    int a, b;

    while (cin >>r>>c) {
        cin >>n;

        memset(Fields, false, sizeof(Fields));

        for (i=0; i<n; ++i) {
            cin >>points[i].x>>points[i].y;
            Fields[points[i].x][points[i].y] = true;
        }

        qsort(points, n, sizeof(point_st), comp);
        int sum = 0;

        for (i=0; i<n; ++i) {
            for (j=i+1; j<n; ++j) {
                int dx = points[j].x - points[i].x;
                if (dx>0 && ((r-points[i].x)/dx) < sum)  // 剪枝1,当前的可移动点数大于sum(sum为当前最大值)
                    continue;
                int dy = points[j].y - points[i].y;
                a = points[i].x - dx;
                b = points[i].y - dy;
                if (a>0 && a<=r && b>0 && b<=c)  // 剪枝2,该点的前趋点仍然在图中,则证明points[i]点不能作为初始点
                    continue;
                k = calPath(i, j);

                if (k > sum)
                    sum = k;
            }
        }

        cout <<sum<<endl;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/bombe1013/p/3594585.html