记录编号 |
168343 |
评测结果 |
AAAAAAAAAAAAAAA |
题目名称 |
[USACO Mar10]星牛争霸 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.014 s |
提交时间 |
2015-07-03 17:32:58 |
内存使用 |
0.38 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<deque>
#include<vector>
using namespace std;
const double eps=1e-10,pi=acos(-1.0),INF=1e10;
const int SIZE=2010;
class Point{
public:
double x,y;
};
void print(const Point &p){
cout<<"("<<p.x<<" "<<p.y<<")";
}
double cross(const Point &a,const Point &b){
return a.x*b.y-b.x*a.y;
}
class H_Plane{//那啥啥的game,不对plane
public:
double a,b,c;//ax+by<=c
double pa;//极角
void print(void)const{
cout<<"极角:"<<pa<<" 不等式:"<<a<<"x+"<<b<<"y<="<<c;
cout<<" 方程:y="<<-a/b<<"x+"<<c/b<<endl;
}
void assign(char winner,double j1,double j2,double j3,double b1,double b2,double b3){
a=j1-b1,b=j2-b2,c=b3-j3;//这是按Bessie赢算的
if(winner=='J') a*=-1,b*=-1,c*=-1;
pa=atan2(-a,b);
if(pa<0) pa+=2*pi;
}
};
void print(const H_Plane &h){
h.print();
}
bool cmp(const H_Plane &a,const H_Plane &b){
return a.pa<b.pa;
}
bool inside(const Point &p,const H_Plane &h){
return h.a*p.x+h.b*p.y<h.c-eps;
}
Point inter(const H_Plane &s,const H_Plane &t){//要求s,t极角不同
Point ans;
ans.x=(s.b*t.c-s.c*t.b)/(s.b*t.a-s.a*t.b);
ans.y=(s.a*t.c-s.c*t.a)/(s.a*t.b-s.b*t.a);
return ans;
}
void HPL_intersection(H_Plane h[],int n,deque<H_Plane> &Q){
//要求此时已经计算出所有半平面的极角,存于h[1..n]
//Q中返回约束了核的那些半平面
sort(h+1,h+1+n,cmp);
int tot=0;
for(int i=1;i<=n;i++){//多个约束取最紧者
if(tot==0||fabs(h[tot].pa-h[i].pa)>eps) h[++tot]=h[i];
else if(h[i].c<h[tot].c) h[tot]=h[i];
}
n=tot;
Q.clear();
for(int i=1;i<=n;i++){
while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),h[i])) Q.pop_back();
while(Q.size()>=2&&!inside(inter(Q[0],Q[1]),h[i])) Q.pop_front();
Q.push_back(h[i]);
}
while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),Q[0])) Q.pop_back();
}
int check(const vector<Point> &v,const H_Plane &h){
double mx=-INF,mn=INF;
for(int i=0;i<v.size();i++){
double now=h.a*v[i].x+h.b*v[i].y;
mx=max(mx,now);
mn=min(mn,now);
}
if(mx<h.c-eps) return 1;//符合h的判断
else if(mn>h.c+eps) return -1;//不符合h的判断
else return 0;
}
int N,M;
H_Plane test_battle[SIZE];
deque<H_Plane> core;
vector<Point> core_points;
void work(void){
HPL_intersection(test_battle,N,core);
for(int i=0;i<core.size()-1;i++){
core_points.push_back(inter(core[i],core[i+1]));
}
core_points.push_back(inter(core[0],core.back()));
int j1,j2,j3,b1,b2,b3;
H_Plane h;
for(int i=1;i<=M;i++){
scanf("%d%d%d%d%d%d\n",&j1,&j2,&j3,&b1,&b2,&b3);
h.assign('B',j1,j2,j3,b1,b2,b3);
int flag=check(core_points,h);
if(flag==1) printf("B\n");
else if(flag==-1) printf("J\n");
else printf("U\n");
}
}
void read(void){
scanf("%d%d\n",&N,&M);
char c;
int j1,j2,j3,b1,b2,b3;
for(int i=1;i<=N;i++){
scanf("%c%d%d%d%d%d%d\n",&c,&j1,&j2,&j3,&b1,&b2,&b3);
test_battle[i].assign(c,j1,j2,j3,b1,b2,b3);
}
test_battle[++N].assign('B',1,0,0,0,0,100);
test_battle[++N].assign('J',100,0,0,0,0,1);
test_battle[++N].assign('B',0,1,0,0,0,100);
test_battle[++N].assign('J',0,100,0,0,0,1);
test_battle[++N].assign('B',1,0,0,0,100,0);
test_battle[++N].assign('J',100,0,0,0,1,0);
}
int main(){
freopen("starc.in","r",stdin);
freopen("starc.out","w",stdout);
read();
work();
return 0;
}