原题链接
题目分析
题目要求计算在水平线(x轴)上,多个圆在各自覆盖区域内每个整数坐标点处的纵向覆盖点数之和。每个圆在某个x坐标点j处的纵向覆盖点数为2h + 1
,其中h
是满足h ≤ sqrt(r^2 - (x - j)^2)
的最大整数。最终,对每个坐标点j取所有覆盖该点的圆中最大的纵向点数,并将所有j点的结果相加。
解题思路
- 遍历每个圆:对于每个圆,确定它在x轴上的覆盖范围
[x - r, x + r]
。 - 计算纵向覆盖点数:对于每个覆盖的整数坐标j,计算该圆在此处的纵向覆盖点数,公式为
2 * floor(sqrt(r^2 - (x - j)^2)) + 1
。 - 维护最大值:使用哈希表记录每个坐标点j处的最大纵向点数。
- 求和结果:遍历哈希表,将所有坐标点的最大值累加得到最终结果。
代码解析
void xhita() {ll n, m, sum = 0;cin >> n >> m;vector<ll> x(n), r(n);unordered_map<ll, ll> tk;// 输入圆心坐标x和半径rfcin(0, n, x);fcin(0, n, r);for (int i = 0; i < n; i++) {// 遍历该圆覆盖的所有x坐标jfor (int j = x[i] - r[i]; j <= x[i] + r[i]; j++) {// 计算纵向覆盖点数并更新最大值ll h = (ll)sqrt(1.0 * r[i] * r[i] - (x[i] - j) * (x[i] - j));tk[j] = max(tk[j], 2 * h + 1);}}// 累加所有坐标点的最大值for (auto c : tk) {sum += c.second;}cout << sum << endl;
}
示例说明
假设输入为:
2 0
1 3
2 2
- 第一个圆圆心在1,半径2,覆盖x范围[-1, 3]。
- 第二个圆圆心在3,半径2,覆盖x范围[1, 5]。
对于x=1:
- 第一个圆的纵向点数:
2*2 +1=5
。 - 第二个圆的纵向点数:
2*1 +1=3
(距离为2,sqrt(4 - 4)=0)。 - 最终取最大值5。
遍历所有x点并累加最大值即可得到最终结果。