CF1971F Circle Perimeter

题目

Given an integer \(r\), find the number of lattice points that have a Euclidean distance from \((0, 0)\) greater than or equal to \(r\) but strictly less than \(r+1\).

A lattice point is a point with integer coordinates. The Euclidean distance from \((0, 0)\) to the point \((x,y)\) is \(\sqrt{x^2 + y^2}\).
https://codeforces.com/contest/1971/problem/F

Input

The first line contains a single integer \(t\) (\(1 \leq t \leq 1000\)) — the number of test cases.The only line of each test case contains a single integer \(r\) (\(1 \leq r \leq 10^5\)).
The sum of \(r\) over all test cases does not exceed \(10^5\).

6
1
2
3
4
5
1984

Output

For each test case, output a single integer — the number of lattice points that have an Euclidean distance \(d\) from \((0, 0)\) such that \(r \leq d < r+1\).

8
16
20
24
40
12504

题解

解题思路

注意到数据范围为1e5级别,需要线性时间复杂度,故考虑枚举一个数并快速算出另外一个数
对公式\(r \leq \sqrt{x^2 + y^2} \leq r+1\)进行变形,可以得知需要枚举x(范围为\((-r,r)\)),利用公式求出y从而快速计算,注意边界情况:\(x^2+y^2 \leq (r+1)^2-1\)

Code

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
signed main(){
	IOS;
    int _;cin>>_;
    while(_--){
        LL n;cin>>n;
        LL ans=0;
        for(LL i= -n;i<=n;i++){
            LL t1=ceil(sqrtl(n*n-i*i));
            LL t2=sqrtl((n+1)*(n+1)-i*i-1);
            ans+=(t2-t1+1)*2-(t1==0);
        }
        cout<<ans<<endl;
    }
	
	return 0;
}

posted on 2024-06-03 19:36  TaopiTTT  阅读(8)  评论(0编辑  收藏  举报