关于多边形内点数问题的一些变形

最近两次比赛出现两道相同类型的题,有人十几分钟就AC了,而有人卡了俩小时。。。反思。。

 

 先说hdu4353这道题,题意是要求一个从N个点1里边画出一个多边形来,然后给出M个点2。让这个(多边形的面积/多边形内点2的个数)最小。

 描述很复杂。。。但是仔细想想会发现,多边形的点越多,面积也就越大,所以,这里只能画三个点,也就是一个三角形。至于怎么求点2的个数,这是很有必要总结的,祭奠我那苦逼的俩小时吧。。。。

先看一个图: 

这不是立体图,仅仅是个平面图。。。

假设sum[i][j]表示i,j这条线上方这块区域的点的数目

可以看到三角形内点2的数目 = sum[i][j] + sum[j][k] - sum[i][k];

其实更通用一点就是: abs(sum[i][k] - sum[i][j] - sum[j][k]);

既然统计出这些点数来,这个问题基本就解决了。

 HDU 4353的代码:

View Code
const int N = 210;
const int M = 511;

struct Point {
    int x, y;
    bool operator < (const Point& cmp) const {
        return x < cmp.x;
    }
};

Point a[N], b[M];
int sum[N][N];
int n, m;

inline int det(int x1, int y1, int x2, int y2) {
    return x1*y2 - x2*y1;
}

inline int cross(Point a, Point b, Point c) {
    return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
}


int main() {
    //freopen("data.in", "r", stdin);

    int i, j, k, t, cas = 0, cnt;
    double ans, area;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &m);
        REP(i, n)   scanf("%d%d", &a[i].x, &a[i].y);
        REP(i, m)   scanf("%d%d", &b[i].x, &b[i].y);
        sort(a, a + n);

        for(i = 0; i < n; ++i) {
            for(j = i + 1; j < n; ++j) {
                sum[i][j] = 0;
                for(k = 0; k < m; ++k) {
                    if(b[k].x >= a[i].x && b[k].x < a[j].x) {
                        if(cross(a[i], a[j], b[k]) > 0) sum[i][j]++;
                    }
                }
            }
        }
        ans = -1;
        for(i = 0; i < n; ++i) {
            for(j = i + 1; j < n; ++j) {
                for(k = j + 1; k < n; ++k) {
                    cnt = sum[i][k] - sum[i][j] - sum[j][k];
                    if(cnt == 0)    continue;
                    area = double(cross(a[i], a[j], a[k]))/2;
                    if(ans == -1 || fabs(area/cnt) < ans)    ans = fabs(area/cnt);
                }
            }
        }
        if(ans == -1)   printf("Case #%d: -1\n", ++cas);
        else    printf("Case #%d: %.6lf\n", ++cas, ans);
    }
    return 0;
}

 

  还有一个就是多校9上的1001题(HDU 4380)。比上面这个题更直白,需要统计三角形内的点数是不是奇数就可以。。。

 

   

posted @ 2012-08-22 15:12  AC_Von  阅读(433)  评论(0编辑  收藏  举报