ADAM1 - Adrita and Marbles 题解
|| 题目传送门1 || 题目传送门2 ||
题目分析
①圆的方程
题目中给出了一个圆的方程 \(x^2 + y^2 - px-py+z=0\)。
我们可以将其转化为标准圆的方程形式 \((x-h)^2+(y-k)^2=r^2\)。
将完成平方后的表达式代入原方程得到 \((x-\frac{p}{2})^2-\frac{p^2}{4}+(y-\frac{q}{2})^2-\frac{q^2}{4}+z=0\)。
合并同类项得到 \((x-\frac{p}{2})^2 + (y-\frac{q}{2})^2 = \frac{p^2+q^2-4z}{4}\)。
最后得到 \((x-h)^2+(y-k)^2=r^2\)。
其中
圆心为 \((h,k)=(\frac{p}{2},\frac{q}{2})\)。
半径的平方 \(r^2=\frac{p^2+q^2-4z}{4}\)。
②判断弹珠圆心是否在桌子上
弹珠的中心坐标为 \((x,y)\),半径为 \(1\)。根据题目,弹珠在桌子上的条件是:
- 弹珠的中心到圆心的距离小于或等于圆的半径减去弹珠的半径(即 \(r-1\))。
- 题目中说了如果弹珠的中心正好在圆的边界上(距离等于 \(r\)),则认为弹珠在桌子上。
思路实现
这道题只要理解了圆的方程,其实就不难了。只需要按照这个思路编程就可以了:
-
对于每个弹珠,计算其中心到圆心的距离平方。
-
判断该距离平方是否小于或等于 \(r^2\)。
-
统计满足条件的弹珠数量。
最后还要注意最好开个 long long
。因为 \(x^2\) 和 \(y^2\) 最大是可以达到 \(10^{10}\) 的。
代码
#include<bits/stdc++.h>
#define int long long
#define fast_running ios::sync_with_stdio(false),std::cin.tie(0),std::cout.tie(0);
using namespace std;
signed main(){
fast_running;
int T;
cin >> T;
while(T--){
int p, q, z, n, ans = 0;
cin >> p >> q >> z;
cin >> n;
// 计算圆心 (h, k) 和半径平方 r^2
int h = p / 2, k = q / 2;
int r = (p * p + q * q - 4 * z) / 4;
for(int i = 1; i <= n; i++){
int x, y;
cin >> x >> y;
// 计算弹珠中心到圆心的距离平方
int dx = x - h, dy = y - k;
int temp = dx * dx + dy * dy;
// 判断是否在桌子上
if(temp <= r) ++ans;
}
cout << ans << '\n';
}
return 0;
}