题号1174,原题见下图:
解题思路:
解题思路: 把台球看做质点(台球坐标不变,球桌坐标各个边界向里收缩R,得到新的球桌);
假设没边界,求出小球沿着直线的最后坐标x,y;
x,y在球桌内,返回输出否则;
判断小球与哪个边界相撞(判断方法有多中,我的和他们的比起来可能不高大上),以该边界为对称轴,翻转x,y;
再重复上述步骤;
(本应该用递归,但是栈溢出,改了循环)
具体还是看图把:
分解图:
注意事项: 球桌坐标各个边界向里收缩R,即上边界:w-R;
下边界:0+R;左边界:0+R;右边界:L-R;
(注意上下边界,不加R,测试数据也正确,但是大数据误差,出现答案错误)
参考代码:
#include <stdio.h>
#include <math.h>
int n = 0;
double X1, Y1, x, y, R;
void endpoint( double L, double W ); /* x,y is start point X1,Y1 is end point */
int main()
{
double L, W, a, v, s;
scanf( "%lf%lf%lf%lf%lf%lf%lf%lf", &L, &W, &x, &y, &R, &a, &v, &s );
while ( L != 0 && W != 0 && x != 0 && y != 0 && R != 0 && a != 0 && v != 0 && s != 0 )
{
a = a * asin( 1 ) * 2 / 180;
X1 = x + s*v*cos( a );
Y1 = y + s*v*sin( a );
while ( X1<0 || X1>L || Y1<0 || Y1>W )
{
endpoint( L - R, W - R );
}
if ( X1 >= 0 + R && X1 <= L && Y1 >= 0 + R && Y1 <= W )
{
printf( "%.2lf %.2lf\n", X1, Y1 );
}
scanf( "%lf%lf%lf%lf%lf%lf%lf%lf", &L, &W, &x, &y, &R, &a, &v, &s );
}
/*for(int i=0;i<n;i++)
* {
* printf("%.2lf %.2lf\n",xx[i],yy[i]);
*
* }*/
return(0);
}
void endpoint( double L, double W )
{
double upx, downx, righty, lefty, slope;
slope = (Y1 - y) / (X1 - x);
upx = (W - y) / slope + x;
downx = (0.0 + R - y) / slope + x;
righty = slope * (L - x) + y;
lefty = slope * (0.0 + R - x) + y;
if ( Y1 > W && y < W && upx >= 0 + R && upx <= L )
{
x = upx;
y = W;
Y1 = Y1 - 2 * (Y1 - W);
return;
} /* yu shangbianjie xiang jiao */
else
if ( Y1 < 0 + R && y > 0 + R && downx >= 0 + R && downx <= L )
{
x = downx;
y = 0 + R;
Y1 = Y1 - 2 * (Y1 - R);
return;
} /* yu xiabianjie */
else
if ( X1 > L && x < L && righty >= 0 + R && righty <= W )
{
x = L;
y = righty;
X1 = X1 - 2 * (X1 - L);
return;
} /* YU YOU BIANJIE */
else
if ( X1 < 0 + R && x > 0 + R && lefty >= 0 + R && lefty <= W )
{
x = 0 + R;
y = lefty;
X1 = X1 - 2 * (X1 - R);
return;
}
return;
}