Toy Storage POJ

来源:互联网 发布:json.stringify()使用 编辑:程序博客网 时间:2024/06/06 10:52
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 1000 + 10;int m, n;int x1, y1, x2, y2;                 //边界struct box {                        //每一个格子上的属性,右边界坐标以及玩具数量    int u, d, cnt;    bool operator<(const box &rhs)const  {        return d < rhs.d;    }};box boxes[MAXN];                    //每个箱子右侧线的上下两个点,即x的的上下坐标int ans[MAXN];int main() {    while(scanf("%d", &n) == 1 && n) {        //input        memset(boxes, 0, sizeof(boxes));        memset(ans, 0, sizeof(ans));        scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);        for(int i = 0; i < n; ++i) {            scanf("%d%d", &boxes[i].u, &boxes[i].d);        }        boxes[n].u = boxes[n].d = x2;//最后一个格子的右边界        sort(boxes, boxes+n+1);//因为没有交叉,按上或者下从左至右排序就好        //slove        /*根据余切判断分布情况,原理就是,从第一条线开始,选取这条线下顶点做        原点,刚输入的点,这条线的上顶点分别与原点所成的角,余切小的在右边,因为        输入都是合法的(都没有边界上或者外),所以,当如果判断成立的话,该点        一定在这条线的左侧,且在前一线的右侧(如果也在前一条线的左侧,那么计数之        后跳出循环,不会判断当前的线,故不会在线的右侧),        计数就好了,O(mn)最大5000*5000,(还可以用二分优化)        另一种思路是利用叉积判断点在线的哪一侧来确定位置        */        int x, y;        for(int i = 0; i < m; ++ i) {            scanf("%d%d", &x, &y);            for(int j = 0; j <= n; ++j) {                if(((boxes[j].u-boxes[j].d*1.0)/(y1-y2)) > ((x-boxes[j].d*1.0)/(y-y2))) {                    ans[boxes[j].cnt]--;//计数,含有cnt的玩具的箱子数量-1,含有cnt+1数目的玩具的箱子数量+1                    ans[++boxes[j].cnt]++;                    break;                }            }        }        //output        printf("Box\n");        for(int i = 1; i <= m; ++i) {            if(ans[i] > 0) {                printf("%d: %d\n", i, ans[i]);            }//(continue);        }        //  printf("\n");    }    return 0;}