迷你高尔夫球场


18

这是一个迷你高尔夫球洞:

外边界是一个半径为10且中心为(0,0)的圆。内边界是一个半径为3且中心为(0.5)的圆。发球台在(0,-8)。假设球只是半径为0的点。

球的动力学受以下规则支配:

  • 最初,球以能量50和给定角度击中。

    • 角度在笛卡尔坐标系中呈递减角度,因此0°表示直接向右,90°则直接向上,依此类推。
  • 当球撞击内圆或外圆的边缘时,它会根据反射定律从圆上反弹。

    • 在那个点与圆的碰撞角等于反射角。(这里的角度是相对于碰撞点处的圆的切线。)

    • 为了清楚起见,请参见(在第二链路的表示法,R_0 = 0在这个挑战。)

  • 球在移动时会失去能量。

    • 它覆盖的每单位地面都会损失1单位的能量。

    • 每次从墙壁反弹时,都会损失5个单位的能量。

  • 当球用尽能量或掉进洞中时,球停止运动。

    • 如果球以小于等于5的能量击中墙壁,它将停止。

    • 如果它在孔的距离1之内,且能量<10,它会掉入孔中,否则它将继续移动。

挑战

在给定孔的xy坐标的情况下,返回一个角度,您可以按该角度击球,以使球掉入孔中(如果存在该角度)。

输入值

以任何方便的形式输入孔中心的x坐标和y坐标。输入可以来自STDIN(或最接近的替代品),命令行参数或函数参数。

输出量

打印或返回一个角度,以度为单位,可以从发球区击球,使球落入孔中。如果存在这样的角度,则输出应在[0,360)范围内,否则输出应为-1。


您可能想要指定应如何读取x和y值(标准输入,函数参数等)。
Loovjo 2015年

如果没有这样的角度应该返回什么?
Alex A.

我们指定如果有解决方案,该函数将返回[0,360)中的值,否则返回-1。
埃里克·布鲁克斯

我做了一些编辑。如果与您的意图不符,请回滚编辑。
Alex A.

另外,您能否提供至少一个测试用例?
Alex A.

Answers:


4

C,415 430

编辑:就像@Winny提到的那样,退出值不能超过255,所以我不得不增加此代码大小才能打印最多360的值。

假设2个(只有2个)命令行输入(xy)为整数。答案以度为单位打印,如果不存在度,则为-1。

#include <math.h>
#define E(z) {if((e-=5)<0)break;q=n/sqrt(n*n+pow(m-z,2));w=(m-z)/sqrt(n*n+pow(m-z,2));d=(t=d)*(1-2*q*q)-2*f*q*w;f=f*(1-2*w*w)-2*t*q*w;}
main(a,v)char**v;{float D=.01,e,d,f,n,m,p=.0174,q,t,w;a-=4;while(++a<360){n=0,m=-8,d=D*cos(a*p),f=D*sin(a*p),e=50;while(e>0){if((pow(n-atoi(v[1]),2)+pow(m-atoi(v[2]),2)<1)&(e<10)&&printf("%d",a))return;n+=d,m+=f,e-=D;if(n*n+m*m>100)E(0)if(n*n+pow(m-5,2)<9)E(5)}}puts("-1");}

例如

>./golfed 0 2; echo $?
90
>./golfed 0 10; echo $?
0
>./golfed -2 -7; echo $?
12

第一次打高尔夫球;可能会有所改善。如果我们需要更高的精度,我有一个版本,它接受xy并以0.02个字符的.01度精度返回两倍的角度。

可读版本:

#include <math.h>
int main(int argc, char** argv)
{
    // p is roughly pi/180 and q, t, and w are temp vars
    float Delta=.01, energy, delta_x, f(delta_y), n(cur_x), m(cur_y), p=.0174, q, t, w;
    argc -= 4; /*using argc as int for angle*/
    // iterate through each degree
    while (++argc < 360)
    {
        n=0, m=-8, d=D*cos(a*p), f=D*sin(a*p), e=50;
        // then move in discrete .01 steps
        while (e > 0)
        {
            // check to see if we're inside the hole
            if ((pow(n-atoi(v[1]),2) + pow(m-atoi(v[2]),2) < 1) 
                & (e<10) && printf("%d",a)) return;
            // move forward
            n += d, m += f, e -= D;
            // check if we've hit the outer wall
            if (n * n + m * m > 100)
            {
                // if too slow, finish this iteration
                // if not, find reflection vector
                if ((e -= 5) < 0) break;
                q = n / sqrt(n * n + pow(m,2));
                w = (m) / sqrt(n * n + pow(m,2));
                d = (t = d) * (1 - 2 * q * q) - 2 * f * q * w;
                f = f * (1 - 2 * w * w) - 2 * t * q * w;
            }
            // check inner wall collision
            if (n * n + pow(m - 5,2) < 9)
            {
                // if too slow, finish this iteration
                // if not, find reflection vector
                if ((e -= 5) < 0) break;
                q = n / sqrt(n * n + pow(m - 5,2));
                w = (m - 5) / sqrt(n * n + pow(m - 5,2));
                d = (t = d) * (1 - 2 * q * q) - 2 * f * q * w;
                f = f * (1 - 2 * w * w) - 2 * t * q * w;
            }
        }
    }
    // if an angle not found, return -1
    puts("-1");
}

我认为您无法通过返回大于255的值exit(code)。已通过Linux在Linux和FreeBSD上进行了测试echo 'int main(){return 300;}' > test.c && cc test.c && ./a.out; echo $?
Winny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.