ZOJ 3379 Master Spark

計算出中軸能覆蓋到某個點的極角範圍,最大覆蓋次數便是答案。ios

首先把中軸和點重合,此時中軸的角度爲theta = atan(y/x),spa

而後以原點爲圓心旋轉點和拋物線相交求出之間的夾角,code

把x = a*y*y 化成極座標下r cosθ = a *r *r (1 -  cos2θ) ,解方程獲得blog

極角範圍應該爲[theta-θ, theta+θ]。排序

有了極角範圍,排序之後掃描線。事件

寫的時候須當心的坑點:rem

1.theta-θ的範圍可能超過[0, 2*pi],須要取餘。string

2.取餘之後有可能有end < begin的狀況,須要在最左端手動添加事件點。it

3.端點是均可以包括的,當極角相同時,入點事件優先於出點事件。io

/*********************************************************
*            ------------------                          *
*   author AbyssFish                                     *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<numeric>
#include<climits>
using namespace std;


typedef long double ld;
const int maxn = 3e4+1;
double x[maxn], y[maxn];

inline ld sqr(ld x){ return x*x; }
const ld DPI = acosl(-1)*2;

typedef pair<ld,int> ev;
#define fi first
#define se second
vector<ev> evs;
#define pb push_back

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    //cout<<remainder(-1,2);
    int n;
    double a;
    evs.reserve(maxn*3);
    while(~scanf("%d%lf",&n,&a)){
        int i;
        for(i = 0; i < n; i++) scanf("%lf",x+i);
        for(i = 0; i < n; i++) scanf("%lf",y+i);
        ld theta, delta, r, be, ed;
        evs.clear();
        for(i = 0; i < n; i++){
            theta = atan2l(y[i],x[i]);
            r = sqrtl(sqr(x[i])+sqr(y[i]));
            delta = acosl( (-1+sqrtl(1+4*sqr(r)*sqr(a)))/(2*a*r) );
            //if(delta < 0) delta = -delta;
            be = remainderl(theta-delta,DPI);
            ed = remainderl(theta+delta,DPI);
            if(be < 0) be += DPI;
            if(ed < 0) ed += DPI;
            evs.pb(ev(be,-1));
            evs.pb(ev(ed,1));
            if(ed < be){
                evs.pb(ev(0,-1));
            }
        }
        int ans = 0, cur = 0;
        sort(evs.begin(),evs.end());
        for(vector<ev> ::iterator it = evs.begin(); it != evs.end(); it++){
            cur -= it->se;
            //cout<<cur<<endl;
            ans = max(ans,cur);
        }
        printf("%d daze\n", ans);
    }
    return 0;
}
相關文章
相關標籤/搜索