首页 > ACM题库 > HDU-杭电 > HDU 4698-Counting-动态规划-[解题报告]HOJ
2015
09-17

HDU 4698-Counting-动态规划-[解题报告]HOJ

Counting

问题描述 :

Convex hull

样例输入:

2 2 1
1 1

样例输出:

4

转:题意:给定一个二维平面,其中x取值为1-N,y取值为1-M,现给定K个点,问至少包括K个点中的一个的满足要求的<Xmin, Xmax, Ymin, Ymax>共有多少中取值情况。也就是说K个点中至少一个点落在所给定的区间内。

解法:正面求解,由于点只有1000个,因此直接暴力离散化之后的x轴坐标,对于y轴则可以通过增加一个一个加入点,使用一个set来维护纵轴有多少种不同的取法。

代码如下;

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>

#define LL long long
#define mod 1000000007
#define M 1005
#define INF 0x7fffffff

using namespace std;

struct Point
{
    int x, y;
    bool operator < (const Point &temp) const
    {
        if(x!=temp.x) return x<temp.x;
        else return y<temp.y;
    }
    int readPoint()
    {
        return scanf("%d%d", &x, &y);
    }
} p[M];
int n, m, k;
int val[M];
set<int>sset;
set<int>::iterator it;
int main ()
{
    while(~scanf("%d%d%d", &n, &m, &k))
    {
        for(int i = 1; i <= k; ++i)
        {
            p[i].readPoint();
            val[i] = p[i].x;
        }
        sort(p+1, p+1+k);
        sort(val+1, val+1+k);
        int tot = unique(val+1, val+1+k) - val;
        val[0] = 0;
        val[tot] = n+1;
        LL ans = 0;
        for(int i = 1; i < tot; ++i)
        {
            LL tt = 0;
            int pre = val[i]-val[i-1];
            int r;
            for(r = 1; r <= k && p[r].x < val[i]; ++r);
            sset.clear();
            sset.insert(0);
            sset.insert(m+1);
            for(int j = i; j < tot; ++j)
            {
                int top, bottom;
                for( ; r <= k && p[r].x == val[j]; ++r)
                {
                    if(sset.count(p[r].y)) continue;
                    it = sset.lower_bound(p[r].y);
                    top = *it;
                    bottom = *(--it);
                    tt = (tt+(LL)(top-p[r].y)*(p[r].y-bottom)%mod)%mod;
                    sset.insert(p[r].y);
                }
                int rear = val[j+1]-val[j];
                ans = (ans+tt*rear%mod*pre%mod)%mod;
            }
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

参考:http://blog.csdn.net/primoblog/article/details/10725593