Bzoj1829 [Usaco2010 Mar]starc星际争霸

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 152  Solved: 82

Description

《星际争霸2》全面公测啦!Farmer John和Bessie正在测试中——在1v1的战役中使用一些不同的策略来对抗对方的部队。星际争霸2的游戏目标就是在战役中打败你对手的军队。每个选手的军队都在战役中拼杀。一支军队由若干3种不同类型的单位所组成,不同单位有着不同的由正实数表示的,且不被选手所知道的力量值:cattlebruisers 的力量是S1,cow templars 的力量是S2,ultracows的力量是S3。唯一提供的信息是,没有一个单位的力量值超过另一个单位力量值的100倍。一支军队的总力量值,是其中各自单独的单位的力量值的总和。比如一支军队除了其他单位有23个cattlebruisers,那么这支军队单独从cattlebruisers就能获得23*S1的力量值。当两支对立的军队在战役中厮杀,有着更高力量值的军队将获得胜利。如果两支军队的力量值恰好相同,那么将随机产生一个获胜方。Farmer John 和 Bessie 进行了 N (0 <= N <= 300) 局的“测试战役”。在第 i 局测试战役中,Farmer John 有 J1_i 个 cattlebruisers,J2_i 个 cow templars 以及 J3_i 个 ultracows(0 <= J1_i + J2_i + J3_i <= 1,000)。相似的,Bessie的军队有 B1_i 个 cattlebruisers,B2_i 个 cow templars 以及 B3_i 个 ultracows (0 <= B1_i + B2_i + B3_i <= 1,000)。当他们的军队战斗结束后,FJ 和 Bessie 将胜者以一个单独的“胜利字母” V_i 记录下来:"J"表示 Farmer John 赢得了战役;"B" 表示 Bessie 获胜了。虽然这些结果是他们唯一所拥有的信息,但是他们希望预测一些额外的战役的结果——如果告知他们两支对立军队的组成。尽管,可能对于一些比赛他们是无法确定到底哪一方一定能获胜的。给出已经结束的 N 场测试战役的结果,写一个程序来确定(如果可能的话)M (1 <=M <=2,000)场额外战役的获胜方。 所有给出的测试战役的结果都是正确的。至少存在一种合法的力量值的取值符合这些结果。为了示范一下力量值函数的计算,考虑如下战役,并且有 S1=9.0, S2=7.0, S3=4.0 (当然,Farmer John 和 Bessie 都是不知道这3个数值的): 

Input

* Line 1: 两个用空格隔开的整数;N和 M * Lines 2..N+1: 第 i+1 行用7个用空格分开的数据来描述第i场测试战役:V_i, J1_i, J2_i, J3_i,B1_i, B2_i, 和 B3_i——第一个是胜利字母,接下来是6个整数 * Lines N+2..N+M+1: 第i+N+1行描述了第i场额外战役,这里给出6个用空格分开的整数 J1_i, J2_i, J3_i, B1_i, B2_i, 和 B3_i

Output

* Lines 1..M: 第i包含第i场额外战役的结果:"J"表示Farmer John一定能赢,"B"表示Bessie一 定能赢,"U"表示不确定——也就是不可能利用给出的信息推断出谁一定能获胜。

Sample Input

3 3
J 6 5 4 5 4 7
B 5 4 2 3 5 5
J 9 0 10 8 2 7
6 6 4 5 4 7
9 0 10 8 2 6
3 4 8 4 4 6

Sample Output

J
J
U


HINT

一开始的两场战役已经在题目中给出过解释了。最后一场战役是不能利用已有信息推断出结果的。
具体来说,对于 S_1=9.0, S_2=7.0, S_3=4.0 和 S_1=12.0, S_2=20.0, S_3=10.0 
这两组不同的数值都符合输入信息,但是却能使的最后一场测试战役产生不同的结果。

Source

 

数学问题 计算几何 半平面交

似乎很卡精度的样子

设出$x$,$y$,$z$三个未知量分别表示三种单位的战斗力,各种不等式都可以表示成$ax+by+cz0$ 的形式。

注意到z是正数,那么可以将表达式除以z,得到一个直线表达式

对全部的直线做半平面交,可以围出一个凸包(或凸壳?)来。

询问一条直线的时候,将凸包每个顶点带入求值,若值均为正或均为负,则可以判定结果,否则战局不明

 

精度卡飞,干脆学(chao)了Claris神犇的写法

 

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 using namespace std;
  7 const double eps=1e-12;
  8 const double eps2=1e-2;
  9 const int mxn=405;
 10 int read(){
 11     int x=0,f=1;char ch=getchar();
 12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 14     return x*f;
 15 }
 16 struct point{
 17     double x,y;
 18     point operator + (point b){return (point){x+b.x,y+b.y};}
 19     point operator - (point b){return (point){x-b.x,y-b.y};}
 20     point operator * (double v){return (point){x*v,y*v};}
 21     point operator / (double v){return (point){x/v,y/v};}
 22 }p[mxn];
 23 double dot(point a,point b){
 24     return a.x*b.x+a.y*b.y;
 25 }
 26 double Cross(point a,point b){
 27     return a.x*b.y-a.y*b.x;
 28 }
 29 typedef point Vector;
 30 double dist(Vector a){
 31     return sqrt(a.x*a.x+a.y*a.y);
 32 }
 33 struct line{
 34     point x; Vector v;
 35     double a;
 36     void ang(){a=atan2(v.y,v.x);return;}
 37     bool operator < (line b)const{
 38         return a<b.a;
 39     }
 40 }L[mxn],q[mxn];
 41 int cnt=0;
 42 inline void newline(point a,point b){
 43     L[++cnt].x=a;L[cnt].v=b-a;return;
 44 }
 45 point segins(line &a,line &b){//交点 
 46     point x=a.x-b.x;
 47     double t=Cross(b.v,x)/Cross(a.v,b.v);
 48     return a.x+a.v*t;
 49 }
 50 bool Left(point a,line b){
 51     return Cross(b.v,a-b.x)>0;
 52 }
 53 int hd,tl;
 54 void solve(){
 55     newline((point){0,0},(point){100,1});
 56     newline((point){1,100},(point){0,0});
 57     newline((point){0,eps2},(point){100,eps2});
 58     newline((point){100,0},(point){100,100});
 59     newline((point){100,100},(point){0,100});
 60     newline((point){eps2,100},(point){eps2,0});//边界 
 61     
 62     for(int i=1;i<=cnt;i++) L[i].ang();
 63     sort(L+1,L+cnt+1);
 64     hd=tl=1;q[tl]=L[1];
 65     for(int i=2;i<=cnt;i++){
 66         while(hd<tl && !Left(p[tl-1],L[i]))tl--;
 67         while(hd<tl && !Left(p[hd],L[i]))hd++;
 68         if(fabs(Cross(q[tl].v,L[i].v))<eps){
 69             if(!Left(q[tl].x,L[i]))q[tl]=L[i];
 70         }
 71         else q[++tl]=L[i];
 72         if(hd<tl)p[tl-1]=segins(q[tl-1],q[tl]);
 73     }
 74     while(hd<tl && !Left(p[tl-1],q[hd]))tl--;
 75     p[tl]=segins(q[tl],q[hd]);
 76     return;
 77 }
 78 void query(){
 79     int a,b,c,d,e,f;
 80     a=read();b=read();c=read();d=read();e=read();f=read();
 81     a-=d;b-=e;c-=f;
 82     int flag=0;
 83     for(int i=hd;i<=tl;i++){
 84         double tmp=p[i].x*a+p[i].y*b+c;
 85         if(tmp>-eps)flag|=1;
 86         if(tmp<eps)flag|=2;
 87     }
 88     if(flag==1)printf("J\n");
 89     else if(flag==2)printf("B\n");
 90         else printf("U\n");
 91     return;
 92 }
 93 int n,m;
 94 int main(){
 95     freopen("starc.in","r",stdin);
 96     freopen("starc.out","w",stdout);
 97     int i,j;char win[3];
 98     n=read();m=read();
 99     int a,b,c,d,e,f;
100     for(i=1;i<=n;i++){
101         scanf("%s",win);
102         a=read();b=read();c=read();d=read();e=read();f=read();
103         if(win[0]=='B')swap(a,d),swap(b,e),swap(c,f);
104         a-=d;b-=e;c-=f;
105         if(!a && !b)continue;
106         if(b){
107             point A=(point){0,-c/(double)b};
108             point B=(point){100,(-100.0*a-c)/(double)b};
109             point C=A;C.y+=1;
110             if(C.x*a+C.y*b+c>0)newline(A,B);
111                 else newline(B,A);
112         }
113         else{
114             point A=(point){-c/(double)a,0};
115             point B=(point){-c/(double)a,100};
116             point C=A;C.x-=1;
117             if(C.x*a+C.y*b+c>0)newline(A,B);
118                 else newline(B,A);
119         }
120     }
121     solve();
122     while(m--)query();
123     return 0;
124 }

 

posted @ 2017-04-12 23:16  SilverNebula  阅读(369)  评论(0编辑  收藏  举报
AmazingCounters.com