D. 反弹球游戏
Time Limit: 1000msMemory Limit: 65536KB64-bit integer IO format: %lld Java class name: Main
Submit Status
相信大家都玩过反弹球游戏吧(如图),虽然很简单很朴素,但用来打发时间是很不错的。一天,CS正在玩这个游戏,玩了好久有点累了,但是打到一半不想停下,于是CS就想,如果能知道球会在反弹后落在哪一点就好了,这样就可以拜托各位大牛编个程序帮我玩了。请问你可以帮助他解决这个问题吗?
在这里我们把问题简化,假设整个游戏屏在一个二维坐标系中,边框与对应坐标轴平行,游戏屏的左下角对应于坐标系原点,已知游戏屏幕的宽度w(那么右下角就是(w,0))、弹射的出发点的横坐标s(忽略反弹板的厚度,可以认为球在弹出时是在地面(x轴)上的,那么纵坐标自然是0)和第一次与障碍物接触的点p的横纵坐标x和y(这里可以假设反弹球在整个弹射——碰撞——返回地面的过程中除了左右两壁只与障碍物接触一次,而且障碍物为与地面平行的横板),我们想知道球再次与地面接触时的横坐标x0是多少。
Input
数据组数不大于100000组,每组输入一行,为四个用空格分开的整数w, s, x, y,其中2<=w<=109, 0<s,x<w, 0<y<=109,当w=s=x=y=0时表示输入结束。
Output
每组输出一行,对应于每组输入,输出x0,精确到整数。
Sample Input
10 2 4 10
10 4 2 10
10 4 8 10
0 0 0 0
Sample Output
6
0
8
来源: http://acm.bnu.edu.cn/v3/contest_show.php?cid=7670#problem/D
#include <cstdio>
int Cal(int w,int s,int x,int y)
{
if(s==x) return s; //正上方反弹则落地点为原点
if(s>x) //向左弹射
{
int X=2*x-s;//理想偏移量 x-(s-x)得
if(X>=0) return X;
return -X;//几何关系对称得
}
//剩下就是向右偏移了
int X=2*x-s;//理想偏移量
if(X<=w) return X;
return 2*w-X;
}
int main(void)
{
int w,s,x,y;
while(~scanf("%d %d %d %d",&w,&s,&x,&y)&&w&&s&&x&&y)
printf("%d\n",Cal(w,s,x,y));
return 0;
}
精简后
#include <cstdio>
int Cal(int w,int s,int x,int y)
{
if(s==x) return s; //正上方反弹则落地点为原点
int X=2*x-s; //理想偏移量
if(s>x) return X>=0?X:-X; //向左弹射
return X<=w? X:2*w-X; //向右弹射
}
int main(void)
{
int w,s,x,y;
while(~scanf("%d %d %d %d",&w,&s,&x,&y)&&w&&s&&x&&y)
printf("%d\n",Cal(w,s,x,y));
return 0;
}