Bzoj1829 [Usaco2010 Mar]starc星际争霸
2017-04-12 23:16
218 查看
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_iOutput
* Lines 1..M: 第i包含第i场额外战役的结果:"J"表示Farmer John一定能赢,"B"表示Bessie一 定能赢,"U"表示不确定——也就是不可能利用给出的信息推断出谁一定能获胜。Sample Input
3 3J 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
JJ
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+cz≥0$ 的形式。
注意到z是正数,那么可以将表达式除以z,得到一个直线表达式
对全部的直线做半平面交,可以围出一个凸包(或凸壳?)来。
询问一条直线的时候,将凸包每个顶点带入求值,若值均为正或均为负,则可以判定结果,否则战局不明
精度卡飞,干脆学(chao)了Claris神犇的写法
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> using namespace std; const double eps=1e-12; const double eps2=1e-2; const int mxn=405; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct point{ double x,y; point operator + (point b){return (point){x+b.x,y+b.y};} point operator - (point b){return (point){x-b.x,y-b.y};} point operator * (double v){return (point){x*v,y*v};} point operator / (double v){return (point){x/v,y/v};} }p[mxn]; double dot(point a,point b){ return a.x*b.x+a.y*b.y; } double Cross(point a,point b){ return a.x*b.y-a.y*b.x; } typedef point Vector; double dist(Vector a){ return sqrt(a.x*a.x+a.y*a.y); } struct line{ point x; Vector v; double a; void ang(){a=atan2(v.y,v.x);return;} bool operator < (line b)const{ return a<b.a; } }L[mxn],q[mxn]; int cnt=0; inline void newline(point a,point b){ L[++cnt].x=a;L[cnt].v=b-a;return; } point segins(line &a,line &b){//交点 point x=a.x-b.x; double t=Cross(b.v,x)/Cross(a.v,b.v); return a.x+a.v*t; } bool Left(point a,line b){ return Cross(b.v,a-b.x)>0; } int hd,tl; void solve(){ newline((point){0,0},(point){100,1}); newline((point){1,100},(point){0,0}); newline((point){0,eps2},(point){100,eps2}); newline((point){100,0},(point){100,100}); newline((point){100,100},(point){0,100}); newline((point){eps2,100},(point){eps2,0});//边界 for(int i=1;i<=cnt;i++) L[i].ang(); sort(L+1,L+cnt+1); hd=tl=1;q[tl]=L[1]; for(int i=2;i<=cnt;i++){ while(hd<tl && !Left(p[tl-1],L[i]))tl--; while(hd<tl && !Left(p[hd],L[i]))hd++; if(fabs(Cross(q[tl].v,L[i].v))<eps){ if(!Left(q[tl].x,L[i]))q[tl]=L[i]; } else q[++tl]=L[i]; if(hd<tl)p[tl-1]=segins(q[tl-1],q[tl]); } while(hd<tl && !Left(p[tl-1],q[hd]))tl--; p[tl]=segins(q[tl],q[hd]); return; } void query(){ int a,b,c,d,e,f; a=read();b=read();c=read();d=read();e=read();f=read(); a-=d;b-=e;c-=f; int flag=0; for(int i=hd;i<=tl;i++){ double tmp=p[i].x*a+p[i].y*b+c; if(tmp>-eps)flag|=1; if(tmp<eps)flag|=2; } if(flag==1)printf("J\n"); else if(flag==2)printf("B\n"); else printf("U\n"); return; } int n,m; int main(){ freopen("starc.in","r",stdin); freopen("starc.out","w",stdout); int i,j;char win[3]; n=read();m=read(); int a,b,c,d,e,f; for(i=1;i<=n;i++){ scanf("%s",win); a=read();b=read();c=read();d=read();e=read();f=read(); if(win[0]=='B')swap(a,d),swap(b,e),swap(c,f); a-=d;b-=e;c-=f; if(!a && !b)continue; if(b){ point A=(point){0,-c/(double)b}; point B=(point){100,(-100.0*a-c)/(double)b}; point C=A;C.y+=1; if(C.x*a+C.y*b+c>0)newline(A,B); else newline(B,A); } else{ point A=(point){-c/(double)a,0}; point B=(point){-c/(double)a,100}; point C=A;C.x-=1; if(C.x*a+C.y*b+c>0)newline(A,B); else newline(B,A); } } solve(); while(m--)query(); return 0; }
相关文章推荐
- BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交
- BZOJ1829 : [Usaco2010 Mar]starc星际争霸
- bzoj1827 [Usaco2010 Mar]gather 奶牛大集会
- 【bzoj1828】[Usaco2010 Mar]
- BZOJ1828: [Usaco2010 Mar]balloc 农场分配
- bzoj 1827: [Usaco2010 Mar]gather 奶牛大集会
- bzoj:1828: [Usaco2010 Mar]balloc 农场分配
- bzoj 1828: [Usaco2010 Mar]balloc 农场分配【贪心+线段树】
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会
- bzoj 1827: [Usaco2010 Mar]gather 奶牛大集会
- 【bzoj1828】[Usaco2010 Mar]
- BZOJ1827 [Usaco2010 Mar]gather 奶牛大集会
- 【bzoj1827】[Usaco2010 Mar]gather 奶牛大集会 树形dp+贪心
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP
- 【BZOJ】1828: [Usaco2010 Mar]balloc 农场分配(经典贪心)
- 【BZOJ1827】[Usaco2010 Mar]gather 奶牛大集会 树形DP
- BZOJ 1828: [Usaco2010 Mar]balloc 农场分配 线段树 贪心
- 【bzoj1827】[Usaco2010 Mar]gather 奶牛大集会 贪心 树规
- [BZOJ1828][Usaco2010 Mar]balloc 农场分配(贪心+线段树)
- bzoj1828: [Usaco2010 Mar]balloc 农场分配 线段树+贪心