CodeForces 78D Archer's Shot
二分。
统计过程如下图:
先统计红线上的个数,然后统计绿线上的个数,然后统计咖啡色线上的个数......一个一个往下统计就可以了。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-6; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } double r; double sqrt3=sqrt(3.0); double dis(double x,double y) { return x*x+y*y; } bool check(double x,double y) { if(dis(x,y+1)-eps>r*r) return 0; if(dis(x,y-1)-eps>r*r) return 0; if(dis(x+sqrt3/2,y+0.5)-eps>r*r) return 0; if(dis(x+sqrt3/2,y-0.5)-eps>r*r) return 0; if(dis(x-sqrt3/2,y+0.5)-eps>r*r) return 0; if(dis(x-sqrt3/2,y-0.5)-eps>r*r) return 0; return 1; } int main() { while(~scanf("%lf",&r)) { LL ans=0, L=1,R=(LL)2000000,pos; while(L<=R) { LL mid=(L+R)/2; if(check((mid-1)*sqrt3,0)) pos=mid, L=mid+1; else R=mid-1; } LL cnt=0; double x=0,y=-3; while(1) { if(!check(x,y)) break; LL L=1,R=(LL)2000000,pp; while(L<=R) { LL mid=(L+R)/2; if(check(x-(mid-1)*sqrt3/2,y-(mid-1)*1.5)) pp=mid, L=mid+1; else R=mid-1; } pp=1+(pp-1)*2, cnt=cnt+pp, y=y-3; } ans=6*(pos-1)+1+6*cnt; printf("%lld\n",ans); } return 0; }