zoukankan      html  css  js  c++  java
  • 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
    ");
     89     else if(flag==2)printf("B
    ");
     90         else printf("U
    ");
     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 }
  • 相关阅读:
    Node.js 基于 ursa 模块的 RSA 加密解密(已与IOS,Android实现加密通信)
    Mac安装SecureCRT
    lodash underscore 对象数组排序 sortBy 小记
    Spring5--@Indexed注解加快启动速度
    spring的元注解
    RxJava原理学习
    RabbitMQ知识点一
    消息中间件知识点
    Android打开doc、xlsx、ppt等office文档解决方案
    IT观察】网络通信、图片显示、数据库操作……Android程序员如何利用开源框架
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6731131.html
Copyright © 2011-2022 走看看