POJ2318 TOYS(叉积),POJ2398 TOY STORAGE

本文介绍了如何通过计算几何的方法解决线段分割问题,即在给定一组线段和点的情况下,计算这些点落在由线段分割形成的区域中的数量。通过实现模板函数和操作符重载,提供了高效且简洁的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意,给出一堆线段和点,求线段分割的区域中点的个数.

计算几何基础题的模板差不多也搞出来了...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
const double EPS = 1e-8;
using namespace std;
/********************************/

int dcmp(double x){
    if(fabs(x) < EPS)
            return 0;
    if(x < 0)   return -1;
    return 1;//1为正,-1为负,0为等
}
struct point{
    double x , y;
    point(double x = 0,double y= 0):x(x),y(y){}

/************************************/
};
typedef point Vector;
point operator + (const Vector &a , const Vector &b){
    return Vector(a.x + b.x,a.y + b.y);
}
point operator - (const Vector &a , const Vector &b){
    return Vector(a.x - b.x,a.y - b.y);
}
point operator * (const Vector &a , const double &p){
    return Vector(a.x * p,a.y * p);
}
point operator / (const Vector &a , const double &p){
    return Vector(a.x / p,a.y / p);
}
bool operator < (const point &a,const point &b){
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
bool operator == (const point &a,const point &b){
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) ==0;
};
double cross(const Vector &a ,const Vector &b)
{
    return (a.x * b.y - a.y * b.x);
}
point edge[6000][2];
int cnt[6000];
int main()
{
    //freopen("in.txt","r",stdin);
    int n , m;
    int x1 ,x2 ,y1, y2 , Ui,Li;
    while(scanf("%d",&n) , n){

    memset(cnt,0,sizeof(cnt));
    if(n == 0)
        return 0;

    scanf("%d%d%d%d%d" , &m,&x1,&y1,&x2,&y2);
    edge[0][0] = point(x1 , y1);
    edge[0][1] = point(x1 , y2);
    for(int i = 1 ;i <= n ; i++){
        scanf("%d%d",&Ui,&Li);
        edge[i][0] = point(Ui , y1);
        edge[i][1] = point(Li , y2);
    }
    edge[n+1][0] = point(x2,y1);
    edge[n+1][1] = point(x2,y2);
    int findx,findy;
    point d;
    for(int c = 0 ;c < m ; c++){
        scanf("%d%d" , &findx , &findy);
        d = point(findx,findy);
        for(int i = 1; i <= n+1 ;i++){
            if(cross(edge[i][1] - edge[i][0] , d - edge[i][0]) <0)
                    {
                        cnt[i-1]++;
                        break;
                    }
        }
    }
    for(int i = 0 ;i <= n; i++)
            printf("%d: %d\n",i,cnt[i]);
    printf("\n");
    }
    return 0;
}



#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
const double EPS = 1e-8;
using namespace std;
/********************************/

int dcmp(double x){
    if(fabs(x) < EPS)
            return 0;
    if(x < 0)   return -1;
    return 1;//1为正,-1为负,0为等
}
struct point{
    double x , y;
    point(double x = 0,double y= 0):x(x),y(y){}

/************************************/
};
typedef point Vector;
point operator + (const Vector &a , const Vector &b){
    return Vector(a.x + b.x,a.y + b.y);
}
point operator - (const Vector &a , const Vector &b){
    return Vector(a.x - b.x,a.y - b.y);
}
point operator * (const Vector &a , const double &p){
    return Vector(a.x * p,a.y * p);
}
point operator / (const Vector &a , const double &p){
    return Vector(a.x / p,a.y / p);
}
bool operator > (const point &a,const point &b){
return a.x > b.x;
}
bool operator == (const point &a,const point &b){
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) ==0;
};
double cross(const Vector &a ,const Vector &b)
{
    return (a.x * b.y - a.y * b.x);
}
point edge[2000][2];
int cnt[2000];
int res[2000];
int main()
{
    //freopen("in.txt","r",stdin);
    int n , m;
    int x1 ,x2 ,y1, y2 , Ui,Li;
    while(scanf("%d",&n) , n){

    memset(cnt,0,sizeof(cnt));
    memset(res,0,sizeof(res));
    if(n == 0)
        return 0;

    scanf("%d%d%d%d%d" , &m,&x1,&y1,&x2,&y2);

    edge[0][0] = point(x1 , y1);
    edge[0][1] = point(x1 , y2);
    for(int i = 1 ;i <= n ; i++){
        scanf("%d%d",&Ui,&Li);
        edge[i][0] = point(Ui , y1);
        edge[i][1] = point(Li , y2);
    }
    edge[n+1][0] = point(x2,y1);
    edge[n+1][1] = point(x2,y2);

    for(int i = 1 ; i <= n;i++)
            for(int j = 1 ; j<= n-i ; j++)
                if(edge[j][0] > edge[j+1][0]){
                    swap(edge[j][0],edge[j+1][0]);
                    swap(edge[j][1],edge[j+1][1]);
                }

    int findx,findy;
    point d;
    for(int c = 0 ;c < m ; c++){
        scanf("%d%d" , &findx , &findy);
        d = point(findx,findy);
        for(int i = 1; i <= n+1 ;i++){
            if(cross(edge[i][1] - edge[i][0] , d - edge[i][0]) <0)
                    {
                        cnt[i-1]++;
                        break;
                    }
        }
    }
    printf("Box\n");
    for(int i = 0 ;i <= n;i++)
            res[cnt[i]]++;
    for(int i= 1 ;i < 1999;i++)
            if(res[i] != 0)
                printf("%d: %d\n",i,res[i]);

    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值