CF2120B Square Pool 题解

· · 题解

CF2120B Square Pool 题解

Update 2025/7/26:

修改了措辞

题目大意

在一个边长为 s 的方形球桌上,四个角落有四个球袋,坐标分别为 (0,0)(0,s)(s,0)(s,s)。球桌内有 k 个球,每个球都从初始位置 (x,y)45° 角打出。它的方向与 d_xd_y 有关。碰到台桌会无损耗地反弹,速度不变。物理学不存在了。最后要求有多少个球能落入球袋。球碰撞了等于没碰撞。

解题思路

首先,我们要了解台球的反弹。学过初中数学的同学都知道,台球中打出球的路径入射角等于反射角。

即:

根据球的运动方向和初始位置,可推导出球能落入球袋的条件:

  1. dx=1dy=1 时,球的运动方向是向右上方,此时需满足 x=y ,才能最终到达 (s,s) 球袋。
  2. dx=1dy=-1 时,球的运动方向是向右下方,此时需满足 x+y=s,才能最终到达 (s,0) 球袋。
  3. dx=-1dy=1 时,球的运动方向是向左上方,此时需满足 x+y=s,才能最终到达 (0,s)球袋。
  4. dx=-1dy=-1时,球的运动方向是向左下方,此时需满足 x=y,才能最终到达 (0,0) 球袋。

代码实现

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int k,s;
        scanf("%d%d",&k,&s);
        int count=0;
        for(int i=0;i<k;++i){
            int dx,dy,x,y;
            scanf("%d%d%d%d",&dx,&dy,&x,&y);
            if(dx==1&&dy==1){
                if(x==y)
                    count++;
            }
            else if(dx==1&&dy==-1){
                if(x+y==s)
                    count++;
            }
            else if(dx==-1&&dy==1){
                if(x+y==s)
                    count++;
            }
            else{
                if(x==y)
                    count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}

马蜂不良,见谅。