poj 2318 与 poj 2398计算几何 叉乘积运用

来源:互联网 发布:空间大师软件效果图 编辑:程序博客网 时间:2024/05/17 22:27

原文链接

给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数。

 

解答:对每个玩具,二分线段下标,判断在线段左边还是右边,找到之后进行统计即可



误区:开始第一反应是判断点在矩形内外的问题,但是依次判断,明显会超时的



#include<stdio.h>#include<iostream>#include<math.h>#include<string.h>using namespace std;#define MAX 5010struct Point{    int x;    int y;}p1[MAX], p2[MAX],t[MAX];int num[MAX];int Area2(Point p2, Point p3, Point p1){    int temp = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);    return temp;}void Bsearch(Point a, int n){    int l, r, mid;    l = 1; r = n;  //l从1开始    while (l < r)    {        mid = (l + r) >> 1;        if (Area2(p1[mid], p2[mid], a) > 0)        {            l = mid + 1;        }        else        {            r = mid;        }    }    if (Area2(p1[l], p2[l], a) < 0)    {        num[l - 1]++;    }    else    {        num[l]++;    }}int main(){  //freopen("E:\input.txt", "r", stdin);    int m;    int n;    int i, j;    Point point1, point2;    while ((scanf("%d%d", &n, &m)) && n != 0)    {       memset(p1, 0, sizeof(p1));       memset(p2, 0, sizeof(p2));       memset(t, 0, sizeof(t));       memset(num, 0, sizeof(num));       scanf("%d%d%d%d", &point1.x, &point1.y, &point2.x, &point2.y);       for(i = 1; i <= n; i++)       {           scanf("%d%d", &p1[i].x, &p2[i].x);           p1[i].y = point1.y;           p2[i].y = point2.y;       }       for (j = 0; j < m; j++)       {           scanf("%d%d", &t[j].x, &t[j].y);           Bsearch(t[j], n);       }       for (i = 0; i <= n; i++)       {           printf("%d: %d\n", i, num[i]);       }       printf("\n");    }    return 0;}

参考BLOG:poj2318


升级版:POJ2398

只是中间的n个隔板未排序,输出的是装有i个玩具的区域的个数,其他完全一样

#include<stdio.h>#include<iostream>#include<algorithm>#include<math.h>#include<string.h>using namespace std;#define MAX 1010struct Point{    int x;    int y;}p1[MAX], p2[MAX],t[MAX];struct Line{    Point po1;    Point po2;}L[MAX];int num[MAX], num1[MAX];bool cmp(Line a, Line b){    return a.po1.x < b.po1.x;}int Area2(Point p2, Point p3, Point p1){    int temp = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);    return temp;}void Bsearch(Point a, int n){    int l, r, mid;    l = 1; r = n;  //l从1开始    while (l < r)    {        mid = (l + r) >> 1;        if (Area2(L[mid].po1, L[mid].po2, a) > 0)        {            l = mid + 1;        }        else        {            r = mid;        }    }    if (Area2(L[l].po1, L[l].po2, a) < 0)    {        num[l - 1]++;    }    else    {        num[l]++;    }}int main(){  freopen("E:\input.txt", "r", stdin);    int m;    int n;    int i, j;    Point point1, point2;    while ((scanf("%d%d", &n, &m)) && n != 0)    {       memset(p1, 0, sizeof(p1));       memset(p2, 0, sizeof(p2));       memset(t, 0, sizeof(t));       memset(num, 0, sizeof(num));       memset(num1, 0, sizeof(num1));       scanf("%d%d%d%d", &point1.x, &point1.y, &point2.x, &point2.y);       for(i = 1; i <= n; i++)       {           scanf("%d%d", &p1[i].x, &p2[i].x);           L[i].po1.x = p1[i].x;           L[i].po2.x = p2[i].x;           L[i].po1.y = point1.y;           L[i].po2.y = point2.y;       }       sort(L, L + n + 1, cmp);       for (j = 0; j < m; j++)       {           scanf("%d%d", &t[j].x, &t[j].y);           Bsearch(t[j], n);       }       for (i = 0; i <= n; i++)       {           if (num[i])           {               num1[num[i]]++;           }       }       printf("Box\n");       for (i = 1; i <= m; i++)       {           if (num1[i])           {               printf("%d: %d\n", i, num1[i]);           }       }       //printf("\n");    }    return 0;}

参考BLOG:

poj2318 poj2398





0 0