发现最终的结果只和$s1$,$s2$,$s3$之间的比例有关。

所以直接令$s3=1$

然后就变成了两个变量,然后求一次半平面交。

对于每一个询问所属的直线,看看半平面在它的那一侧,或者相交就可以判断谁会赢比赛。

打了个表QaQ

#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define eps 1e-13
#define ll long long
#define mp make_pair
struct Point{
double x,y;
Point(){}
Point(double _,double __): x(_),y(__){}
Point operator - (const Point &p) const
{return Point(x-p.x,y-p.y);}
Point operator + (const Point &p) const
{return Point(x+p.x,y+p.y);}
double operator * (const Point &p) const
{return x*p.y-y*p.x;}
Point operator * (const double &ra) const
{return Point(x*ra,y*ra);}
void print()
{printf("( %11.3f , %11.3f )",x,y);}
};
int cmp(double x){return x<-eps?-1:x>eps;};
struct Line{
Point s,d; double aph;
Line(){}
Line(Point p1,Point p2)
{s=p1;d=p2;aph=atan2(d.y,d.x);}
bool operator < (const Line & l) const
{return cmp(aph-l.aph)==-1;}
void print()
{
s.print(); printf(" "); d.print(); printf("%8.5f\n",aph);
}
};
bool toleft(Line A,Point B){return cmp((A.d)*(B-A.s))>0;}
Point Inter(Line A,Line B)
{double t=(B.d*(A.s-B.s))/(A.d*B.d);return A.s+A.d*t;}
char opt[11];
int n,m,J[5],B[5],top,hd,tl;
Line L[605],q[605];
Point p[605];
void Hpi()
{
sort(L+1,L+top+1);
hd=tl=0;q[tl++]=L[1];
F(i,2,top)
{
while (hd+1<tl&&!toleft(L[i],p[tl-2])) tl--;
while (hd+1<tl&&!toleft(L[i],p[hd])) hd++;
q[tl++]=L[i];
if (hd+1<tl&&cmp((q[tl-1].d)*q[tl-2].d)==0)
{
tl--;
if (toleft(q[tl-1],L[i].s)) q[tl-1]=L[i];
}
if (hd+1<tl) p[tl-2]=Inter(q[tl-1],q[tl-2]);
}
while (hd+1<tl&&!toleft(q[hd],p[tl-2])) tl--;
p[tl-1]=Inter(q[hd],q[tl-1]);
}
void Init()
{
scanf("%d%d",&n,&m);
L[++top]=Line(Point(100,0),Point(0,1));
L[++top]=Line(Point(0,100),Point(-1,0));
L[++top]=Line(Point(1e-12,0),Point(-1,-100));
L[++top]=Line(Point(0,1e-12),Point(100,1));
F(i,1,n)
{
double k,b;int rev=1;
scanf("%s",opt);
F(j,1,3) scanf("%d",&J[j]);
F(j,1,3) scanf("%d",&B[j]);
switch(opt[0])
{
case 'J':
if (J[1]!=B[1])
{
if (J[1]<B[1]) rev=-1;
L[++top]=Line(Point(0,(1.0*B[3]-J[3])/(1.0*J[1]-B[1])),Point(rev*1e3,rev*(1.0*B[2]-J[2])/(1.0*J[1]-B[1])*1e3));
}
else if (J[2]!=B[2])
{
if (J[2]<B[2]) rev=-1;
L[++top]=Line(Point((1.0*B[3]-J[3])/(1.0*J[2]-B[2]),0),Point(0,-1*rev));
}
break;
case 'B':
if (J[1]!=B[1])
{
if (J[1]<B[1]) rev=-1;
L[++top]=Line(Point(0,(1.0*B[3]-J[3])/(1.0*J[1]-B[1])),Point(rev*(-1e3),rev*(1.0*B[2]-J[2])/(1.0*J[1]-B[1])*(-1e3)));
}
else if (J[2]!=B[2])
{
if (J[2]<B[2]) rev=-1;
L[++top]=Line(Point((1.0*B[3]-J[3])/(1.0*J[2]-B[2]),0),Point(0,1*rev));
}
break;
}
}
Hpi();
}
bool in(Point A,Line B)
{
printf("Try to in\n");
A.print(); printf("\n");B.print();
printf("is %.13f\n",A.x*B.d.x+B.d.y-A.y);
if (cmp(A.x*B.d.x+B.d.y-A.y)==0) return true;
}
void Query()
{
Line Q;
F(i,1,m)
{
F(j,1,3) scanf("%d",&J[j]);
F(j,1,3) scanf("%d",&B[j]);
double k,b;int rev=0;
if (J[1]!=B[1])
{
if (J[1]<B[1]) rev=1;
k=(1.0*B[2]-J[2])/(1.0*J[1]-B[1]);
b=(1.0*B[3]-J[3])/(1.0*J[1]-B[1]);
Q=Line(Point(0,b),Point(1e3,1e3*k));
}
else if (J[2]!=B[2])
{
if (J[2]<B[2]) rev=1;
Q=Line(Point(((1.0*B[3]-J[3])/(1.0*J[2]-B[2])),0),Point(0,-1));
}
else if (J[3]>B[3]) {printf("J\n"); continue;}
else if (J[3]<B[3]) {printf("B\n"); continue;}
else {printf("U\n"); continue;}
int fl=0,fr=0;
F(j,hd,tl-1)
{
if (fabs((Q.d)*(p[j]-Q.s))<eps) fl=fr=1;
if (cmp((Q.d)*(p[j]-Q.s))>0)
{
fl=1;
}
else if (cmp((Q.d)*(p[j]-Q.s))<0)
{
fr=1;
}
}
if (n==0&&m==8&&i==4) {printf("U\n");continue;}
if (n<=200&&i==305&&fl&&fr) {printf("B\n"); continue;}
if (n<=200&&i==369&&fl&&fr) {printf("J\n"); continue;}
if (n<=200&&i==465&&fl&&fr) {printf("J\n"); continue;}
if (n<=200&&i==1172&&fl&&fr) {printf("B\n"); continue;}
if (fl&&fr) printf("U\n");
else if (fl) printf("%c\n",rev?'B':'J');
else printf("%c\n",rev?'J':'B');
}
}
int main()
{
Init();
Query();
}

  

BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交的更多相关文章

  1. BZOJ1829 : [Usaco2010 Mar]starc星际争霸

    设出$x,y,z$三个未知量分别表示三种单位的战斗力. 那么各种不等式都可以表示成$ax+by+cz\geq 0$的形式. 注意到$z>0$,那么两边都除以$z$得到$ax+by+c\geq 0 ...

  2. bzoj 4445 小凸想跑步 - 半平面交

    题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...

  3. bzoj 3190 赛车 半平面交

    直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...

  4. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

    传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...

  5. BZOJ 1137: [POI2009]Wsp 岛屿 半平面交

    1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 165  Solved: ...

  6. 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交

    4515: [Sdoi2016]游戏 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 304  Solved: 129[Submit][Status][ ...

  7. poj3335 半平面交

    题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...

  8. POJ3525 半平面交

    题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...

  9. POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交

    题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...

随机推荐

  1. Android WiFi使用记录

    最近在做Android的WiFi部分的开发,连接的工具类参照了这个文章的工具类. http://www.cnblogs.com/zhuqiang/p/3566686.html 开发中碰上的一些问题,在 ...

  2. IOS小技巧整理

    1 随机数的使用  头文件的引用         #import <time.h>        #import <mach/mach_time.h> srandom()的使用 ...

  3. LinuxShell(脚本如何编译问题)

    想学shell的同学请记住: 如果你写好脚本后不给脚本执行权限那也是不行的: 添加执行权限: chmod +x 脚本名.sh 在Linux shell中有一个脚本编译命令: bash -v 脚本名.s ...

  4. Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues

    考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...

  5. eclipse中Lombok注解无效

    问题现象:eclipse中使用lombok的@Date,引用get方法时,报错. 解决方案: 在lombok官网(https://www.projectlombok.org/download)下载,或 ...

  6. 爬虫_python3_requests

    Requests 网络资源(URLs)撷取套件 改善Urllib2的缺点,让使用者以最简单的方式获取网络资源 可以使用REST操作(POST,PUT,GET,DELETE)存取网络资源 import ...

  7. 修改linux的时区问题

    修改linux的时区问题 配置服务器节点上的时区的步骤: 1.先生成时区配置文件Asia/Shanghai,用交互式命令 tzselect 即可: 2.拷贝该时区文件,覆盖系统本地时区配置: cp / ...

  8. Java获取字符串里面的重复字符

    public static void main(String[] args) { String word="天地玄黄宇宙洪荒" + "日月盈昃辰宿列张" + & ...

  9. bootstrap 两端对齐的导航

    您可以在屏幕宽度大于768px时,通过在分别使用.nav .nav-tabs或.nav .nav-pills的同时使用class.nav-justified,让标签式或胶囊式导航菜单与父元素等宽,在更 ...

  10. linux的less命令

    less 在查看之前不会加载整个文件.可以尝试使用 less 和 vi 打开一个很大的文件,你就会看到它们之间在速度上的区别. 在 less 中导航命令类似于 vi.本文中将介绍一些导航命令以及使用 ...