HDU 5515 Game of Flying Circus

传送门
题意:两个人玩一个游戏,他们站在一个矩形的一角,矩形的每条边为300米,每个角被标为1,2,3,4,(他们一开始在1号位置),他们要依此跑过2,3,4,回到1,每个角先到的人会得到1分(当然最初的时候1号点是不算的,要转一圈回来先到的得分),其中一个人跑的很快(记作Speeder),能以V2速度跑,所以他必定直接按路线跑,即沿着矩形边框跑,但是另一个人跑的满,为V1的速度(V1<=V2),但是他很擅长打架(Fighter),能再跑的途中与Speeder战斗,并必定打败S,得到1分,且S会被晕T秒,问你最后F会赢不,输出Yes/No。
范围:所有数小于2000
解法:很明显, F要赢必定要打架,所以除了打架拿到的一分外,他还要至少获得2分才行,那么他可以选择的狙击策略(打晕Speeder!)必然是在最上的那条边或者最右的那条边,同时可以发现越早打晕越好(因为F要重新跑到2号点开始,因为他为了狙击S肯定不会先到2号点),然后枚举S剩下没跑的点谁先到,计算得分比一比就好啦。

【题意】
一个正方形球场。每个角都有一个浮标。按照顺时针方向,依次编号为#1,#2,#3,#4。
两个运动员开始都在1号球杆,他们要先后触碰2号,3号,4号,1号球杆,绕圈一周。

游戏规则:
1,对于任何一个浮标,如果你触碰的时间比对手早,那么你可以得到1分。但是触碰浮标的顺序必须严格是#2,#3,#4,#1。
2,如果你和对手同时到达了一个位置。你们可以打一场,赢的人得一分。但是为了保证比赛的平衡,2个运动员不允许在#2被触碰之前打架。

我们的速度是v1,对手的速度是v2,满足: 0<v1<=v2<=2000
对手会严格按照矩形的边,即按照 1>2>3>4>1 的顺序移动。
我们一定能打过对手,于是我们决定触发有且仅有一次战斗。这会使得我们多得到1分,并且使得对手立刻眩晕T秒。
如果2个人同时到触碰一个点,这个点的得分会给与我们,且我们还可以发动与对手的战斗。
如果2个人恰好在一个点相遇,如果对手碰过上一个浮标,那这个点的得分会给对手。
让你输出是否我们有可能得分比对手高。可能便输出Yes,不可能则输出No。

【类型】
阅读理解 解方程 坑B题

【分析】
这题的逻辑可以很清楚。
1,如果速度相同,那么我们必胜。
2,如果速度不同,我们有意义的阻截位置,要不是在2->3,要不是在3->4。
因为我们最终肯定要沿着#2->#3->#4->#1的顺序走,所以肯定满足——触碰位置越早越好。

所以存在三个判定点,
1,速度相同,我方必胜。
2,[#2 ~ #3)之间相遇,看我方能否先到达#4。
3,[#3 ~ #4)之间相遇,看我方能否先到达#1。
4,[#4 ~ #1)相遇,我方必败。

【时间复杂度&&优化】
O(T*二分)

【数据】
Input
2
1 10 13
100 10 13

Output
Case #1: No
Case #2: Yes

specail(恰好相遇于#4):
2000 100 300
我们和对方都同时在第3s到达,我方必败。

special(恰好相遇于#4前):
2000 100.01 300
眩晕时间很长,我方胜。

special[1+]
12.25 100.01 300
恰好胜

special[2+]
12.24 100.01 300
恰好败

#include <bits/stdc++.h>
using namespace std;
#define prt(k) cerr<<#k" = "<<k<<endl
typedef long long LL;
const int inf = 0x3f3f3f3f;
double T, V1, V2;
#define SQR(x) ((x)*(x))
#define sqr SQR
int main()
{
    int re,ca=1; cin>>re;
    while (re--) {
        scanf("%lf%lf%lf", &T, &V1, &V2);
        printf("Case #%d: ", ca++);
        double A = SQR(V1), B = SQR(V2);
        if (fabs(V1 - V2) < 1e-7) { puts("Yes"); continue;;}
        if (V2 + 1e-7 <= sqrt(2) * V1) {
            double d = 4*A*A - 4*sqr(B-A);
            d = sqrt(max(d,0.0));
            double x = (2 * A - d) / (2 * (B - A));
            int sa = 1, sb = 1;
            for (double y=1;y<=3;y++) {
                if ((x+y)*300/V1 + 1e-7 <= T+(y-x)*300/V2) sa ++;
                else sb ++;
            }
            if (sa > sb) {
                puts("Yes");
                continue;
            }
        }      
        if (V1 * 3  <= V2 ) {
            puts("No");
            continue;
        }
        double D = 36*A*A - 4*(B-A)*(B-9*A);
        D = sqrt(max(D, 0.0));
        double x = (-6*A + D) / (2*(B-A));
        int sa = 1, sb = 2;
        double t = sqrt(1+(1-x)*(1-x));    
        for (double y = 0;y<=1;y++) {
            double T1 = (t + 2 + y) * 300 / V1;
            double T2 = T + (x + y)*300 / V2;
            if (T1 <= T2) sa ++;
            else sb++;
        }
        puts(sa > sb ? "Yes" : "No");   
    }
}

你可能感兴趣的:(游戏)