POJ 2398 Toy Storage(叉积+二分)

题目链接:POJ 2398 Toy Storage

之前做的类似题目:POJ 2318 TOYS

【题意】跟之前做的POJ 2318差不多额,给你一个矩形,有被若干直线分成N个格子,给出M个点(玩具)的坐标,问你放有t个玩具的格子的个数。

【思路】其实跟POJ 2318差不多,利用叉积+二分,但是本题中直线的输入不是按顺序的,要进行排序,才能做二分。开始写错了构造函数,然后就一直不对啊,看来C++的学习之路还很远啊。

/*
** POJ 2398 Toy Storage
** Created by Rayn @@ 2014/05/05
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 1010;
const int INF = 0x3f3f3f3f;

struct Point {
    double x, y;
    Point(double a=0, double b=0): x(a), y(b) {}
} dot[MAX];

struct Line {
    double up, low;
    bool operator < (const Line& rhs) const {
        double x1 = min(up, low);
        double x2 = min(rhs.up, rhs.low);
        if(x1 == x2)
            return max(up, low) < max(rhs.up, rhs.low);
        else
            return x1 < x2;
    }
} line[MAX];

int num[MAX], ans[MAX];

double Cross(Point A, Point B, Point C)
{
    return (C.x-A.x)*(B.y-A.y)-(B.x-A.x)*(C.y-A.y);
}
int main()
{
#ifdef _Rayn
    freopen("in.txt", "r", stdin);
#endif

    int n, m;
    double x1, y1, x2, y2;

    while(scanf("%d", &n) != EOF && n)
    {
        scanf("%d%lf%lf%lf%lf", &m, &x1, &y1, &x2, &y2);
        //printf("%d %d\n", n, m);
        for(int i=0; i<n; ++i)
        {
            scanf("%lf%lf", &line[i].up, &line[i].low);
        }
        sort(line, line+n);
        line[n].up = line[n].low = x2;

        memset(num, 0, sizeof(num));
        memset(ans, 0, sizeof(ans));
        for(int i=0; i<m; ++i)
        {
            scanf("%lf%lf", &dot[i].x, &dot[i].y);
            int left = 0, right = n, mid = 0;
            while(left <= right)
            {
                mid = (left + right) / 2;
                Point b(line[mid].low, y2);
                Point c(line[mid].up, y1);
                if(Cross(dot[i], b, c) > 0)
                    left = mid + 1;
                else
                    right = mid - 1;
            }
            num[left]++;
        }
        for(int i=0; i<=n; ++i)
        {
            if(num[i])
                ans[num[i]]++;
        }
        printf("Box\n");
        for(int i=0; i<=n; ++i)
        {
            if(ans[i])
                printf("%d: %d\n", i, ans[i]);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值