poj 2318 TOYS 与 poj 2398 Toy Storage(叉积的应用:点在线段的左边或者右边)

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/83479695

题目链接:poj 2318

题意:给你一个盒子的俯视图,从左到右将每个格子划分为0,1,2...n;给你一些点的坐标,让你输出每个格子里点的个数。

题解见代码:


///向量P和向量Q ,假如P*Q>0 ,P在Q的顺时针方向
///p*Q<0,P在Q的逆时针方向上,
///点a在线段bc的左边,则它们的叉积小于0,点a在线段bc的右边,则它们的叉积大于0,
///https://blog.csdn.net/wangzhen_yu/article/details/44177449
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

struct point{
    double x,y;
    point(double x=0,double y=0):x(x),y(y){ }
};

struct line{
    point S;
    point E;
}card[5050];

point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,double p) { return point(a.x*p,a.y*p);}
point operator / (point a,double p){ return point(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);
}
const double esp=1e-10;
int dcmp(double x){
    if(fabs(x)<esp) return 0;
    else return x<0?-1:1;
}
bool operator ==(const point &a,point &b){
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}

double Cross(point a,point b){ return a.x*b.y-a.y*b.x;}
double area2(point a,point b,point c){ return Cross(b-a,c-a);}

int sum[5050];
int main()
{
    int n,m;
    double x1,y1,x2,y2;
    while(scanf("%d",&n)&&n)
    {
        scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);

        card[0].S.x=x1;
        card[0].S.y=y1;
        card[0].E.x=x1;
        card[0].E.y=y2;

        card[n+1].S.x=x2;
        card[n+1].S.y=y1;
        card[n+1].E.x=x2;
        card[n+1].E.y=y2;

        double  l,r;
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&l,&r);
            card[i].S.x=l;
            card[i].S.y=y1;
            card[i].E.x=r;
            card[i].E.y=y2;
        }

        memset(sum,0,sizeof(sum));

        for(int i=1;i<=m;i++)
        {
            point p;
            scanf("%lf%lf",&p.x,&p.y);

            for(int j=0;j<=n;j++)
            {
                ///判断点是不是夹在第j条和第j+1条线段之间
    if(dcmp((area2(p,card[j].S,card[j].E)))*dcmp((area2(p,card[j+1].S,card[j+1].E)))<0){
                    sum[j]++;
//                   
                    break;
                }
            }
        }

        for(int i=0;i<=n;i++)
        {
            printf("%d: %d\n",i,sum[i]);
        }
        puts("");
    }
    return 0;
}

题目链接:http://poj.org/problem?id=2398

题意:跟上一题类似不过这题线段(也就是题目中所说的纸板)不是按照顺序给出的,需要进行排次序,然后题目要求的是有多少个空间里放t个玩具。比如第一组样例中每个空间里都是2个玩具,所以输出2:5.第二组样例有四个空间里有1个玩具,有1个空间里有2个玩具,所以如上输出。

代码如下:

///类似于poj 2318,这里我们采用二分解决方法去做
///向量P和向量Q ,假如P*Q>0 ,P在Q的顺时针方向
///p*Q<0,P在Q的逆时针方向上,
///点a在线段bc的左边,则它们的叉积小于0,点a在线段bc的右边,则它们的叉积大于0
///故我们可以二分隔板,只要叉积小于0的隔板

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;
const int maxn=5050;

struct point
{
    int x,y;
    point(){}
    point(int _x,int _y){
        x=_x;y=_y;
    }
};
point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,double p) { return point(a.x*p,a.y*p);}
point operator / (point a,double p){ return point(a.x/p,a.y/p);}

struct line{
    point S;
    point E;
    line(){}
    line (point _S,point _E){
        S=_S;E=_E;
    }
}card[maxn];

bool operator < (const point &a,const point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double esp=1e-5;
int dcmp(double x){
    if(fabs(x)<esp) return 0;
    else return x<0?-1:1;
}
bool operator == (const point &a,const point &b){
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}

double Cross(point a,point b) { return a.x*b.y-a.y*b.x;}
double area2(point a,point b, point c) {return Cross(b-a,c-a);}


bool cmp(line a,line b){
 return a.S.x<b.S.x;
}

int ans[maxn],num[maxn];///ans[i]表示有多少个玩具在第i块空间,num[i]表示空间内有i个玩具的有多少个空间
int main()
{
    int n,m;
    double x1,y1,x2,y2;

    while(scanf("%d",&n)&&n)
    {
        scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);

        double Ui,Li;

        for(int i=0;i<n;i++){
            scanf("%lf%lf",&Ui,&Li);
            card[i]=line(point(Ui,y1),point(Li,y2));
        }
        card[n]=line(point(x2,y1),point(x2,y2));

        sort(card,card+n+1,cmp);

        double x,y;

        memset(ans,0,sizeof(ans));

        point p;
        while(m--)
        {
            scanf("%lf%lf",&x,&y);
            p=point(x,y);
            int L=0,R=n;
            int item;
            while(L<=R) ///二分
            {
                int mid=(L+R)/2;

                if(dcmp(area2(p,card[mid].S,card[mid].E))<0){ ///满足条件,继续往左缩
                    item=mid;
                    R=mid-1;
                }
                else L=mid+1;

            }
//            printf("item=%d\n",item);
            ans[item]++;
        }

        memset(num,0,sizeof(num));

        for(int i=0;i<=n;i++)
        {
//            printf("ans[%d]=%d\n",i,ans[i]);

            if(ans[i]) num[ans[i]]++;
        }

        printf("Box\n");

        for(int i=1;i<=n;i++)
            if(num[i]) printf("%d: %d\n",i,num[i]);

    }
    return 0;
}



我的标签:不拿奖,誓不成人。

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/83479695