zoukankan      html  css  js  c++  java
  • luoguP4468 [SCOI2007]折纸

    题意

    似乎边界上(折线上、正方形纸片边上)的点认为是(0)

    由于操作次数很少,因此逆着操作,求出所有可能的点,之后正向模拟一遍判断即可。

    求一个点关于一个向量的对称点:用向量旋转求出方向向量即可。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10;
    const double eps=1e-8;
    const double Pi=acos(-1.0);
    const double inf=1e9;
    int n,m;
    struct Point
    {
        double x,y;
        inline double len(){return sqrt(x*x+y*y);}
        Point operator+(const Point a)const{return (Point){x+a.x,y+a.y};}
        Point operator-(const Point a)const{return (Point){x-a.x,y-a.y};}
        Point operator*(const double k){return (Point){x*k,y*k};}
        Point operator/(const double k){return (Point){x/k,y/k};}
        double operator*(const Point a)const{return x*a.y-y*a.x;}
        double operator&(const Point a)const{return x*a.x+y*a.y;}
    }p[1<<maxn];
    inline int dcmp(double x)
    {
        if(fabs(x)<=eps)return 0;
        return x<0?-1:1;
    } 
    bool operator==(Point a,Point b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}
    inline Point get(Point a,Point b){return b-a;}
    struct Line{Point p,v;}line[maxn];
    inline bool cmp(Point a,Point b){return !dcmp(a.x-b.x)?dcmp(a.y-b.y)<0:dcmp(a.x-b.x)<0;}
    inline Point turn(Point a,int op)
    {
    	if(op==1)return (Point){-a.y,a.x};
    	else return (Point){a.y,-a.x};
    }
    inline bool check_left(Point a,Line b)
    {
    	return dcmp(get(b.p,b.v)*get(b.p,a))>0;
    }
    inline bool check_right(Point a,Line b)
    {
    	return dcmp(get(b.p,b.v)*get(b.p,a))<0;
    }
    inline Point rev(Point a,Line b,int op)
    {
    	double h=fabs(get(a,b.p)*get(a,b.v))/get(b.p,b.v).len();
    	Point dir=turn(get(b.p,b.v),op);
    	return a+dir*(2*h/dir.len());
    }
    inline bool check_lim(Point a){return dcmp(a.x)>0&&dcmp(a.x-100)<0&&dcmp(a.y)>0&&dcmp(a.y-100)<0;}
    inline Point work(Point a)
    {
    	for(int i=1;i<=n;i++)
    		if(check_right(a,line[i]))a=rev(a,line[i],1);
    		else if(!check_left(a,line[i]))return (Point){-1,-1};
    	return a;
    }
    inline int query(Point a)
    {
    	int tot=0;
    	p[++tot]=a;
    	for(int i=n;i;i--)
    	{
    		int tmp=tot;
    		for(int j=1;j<=tmp;j++)if(check_left(p[j],line[i]))p[++tot]=rev(p[j],line[i],2);
    	}
    	sort(p+1,p+tot+1,cmp);
    	int cnt=0;
    	p[0]=(Point){-inf,-inf};
    	for(int i=1;i<=tot;i++)if(dcmp(p[i].x-p[i-1].x)!=0||dcmp(p[i].y-p[i-1].y)!=0)p[++cnt]=p[i];
    	tot=cnt;
    	int res=0;
    	for(int i=1;i<=tot;i++)if(check_lim(p[i])&&work(p[i])==a)res++;
    	return res;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%lf%lf%lf%lf",&line[i].p.x,&line[i].p.y,&line[i].v.x,&line[i].v.y);
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++)
    	{
    		double x,y;scanf("%lf%lf",&x,&y);
    		printf("%d
    ",query((Point){x,y}));
    	}
    	return 0;
    }
    
  • 相关阅读:
    挖矿是如何产生比特币的?
    影响世界的100个管理定律
    震撼人心的战争类背景音乐
    一个美国女警的工作记录(转载
    李昌镐:苍老的青春(转载)
    博主简介
    python 中判断变量是否定义
    Reading geometries
    Writing geometries
    Accessing data using cursors
  • 原文地址:https://www.cnblogs.com/nofind/p/12244722.html
Copyright © 2011-2022 走看看