Counting Points

原题链接

题目分析

题目要求计算在水平线(x轴)上,多个圆在各自覆盖区域内每个整数坐标点处的纵向覆盖点数之和。每个圆在某个x坐标点j处的纵向覆盖点数为2h + 1,其中h是满足h ≤ sqrt(r^2 - (x - j)^2)的最大整数。最终,对每个坐标点j取所有覆盖该点的圆中最大的纵向点数,并将所有j点的结果相加。

解题思路

  1. 遍历每个圆:对于每个圆,确定它在x轴上的覆盖范围[x - r, x + r]
  2. 计算纵向覆盖点数:对于每个覆盖的整数坐标j,计算该圆在此处的纵向覆盖点数,公式为2 * floor(sqrt(r^2 - (x - j)^2)) + 1
  3. 维护最大值:使用哈希表记录每个坐标点j处的最大纵向点数。
  4. 求和结果:遍历哈希表,将所有坐标点的最大值累加得到最终结果。

代码解析

void xhita() {
    ll n, m, sum = 0;
    cin >> n >> m;
    vector<ll> x(n), r(n);
    unordered_map<ll, ll> tk;
    
    // 输入圆心坐标x和半径r
    fcin(0, n, x);
    fcin(0, n, r);
    
    for (int i = 0; i < n; i++) {
        // 遍历该圆覆盖的所有x坐标j
        for (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点并累加最大值即可得到最终结果。

posted @ 2025-03-13 16:07  Xhita  阅读(48)  评论(0)    收藏  举报