AOJ 0269 - East Wind

局所的な流行りの風が届いたので解いてみた.
やるだけだけど,sin,cos使い慣れてないのでラジアンで1WA.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>
#include <cstring>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;

const int INF = 1001001001;
const double EPS = 1e-8;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

struct P{
    P(){}
    P(double _r, double _i):r(_r), i(_i){}
    void real(const double& v){r = v;}
    void imag(const double& v){i = v;}
    double r, i;
};

double real(const P& p){return p.r;}
double imag(const P& p){return p.i;}
double norm(const P& p){double r = real(p), i = imag(p); return r * r + i * i;}
double dist(const P& p){return std::sqrt(norm(p));}

P operator+(const P& lhs, const P& rhs){
    return P(real(lhs)+real(rhs), imag(lhs)+imag(rhs));
}
P operator-(const P& lhs, const P& rhs){
    return P(real(lhs)-real(rhs), imag(lhs)-imag(rhs));
}
P operator-(const P& p){
    return P(-real(p), -imag(p));
}

double cross(const P& lhs, const P& rhs){
    return real(lhs)*imag(rhs) - imag(lhs)*real(rhs);
}

double dot(const P& lhs, const P& rhs){
    return real(lhs)*real(rhs) + imag(lhs)*imag(rhs);
}

int H, R, U, M, S;
double du, dm, ds;
P hs[100], us[10], ms[10], ss[10];

bool can(P home, P flower, double d, P wind){
    if(dist(home-flower) > imag(wind)){return false;}
    P center;
    center.real(imag(wind) * std::cos(M_PI / 180.0f * real(wind)));
    center.imag(imag(wind) * std::sin(M_PI / 180.0f * real(wind)));
    double s = cross(center, home-flower) / dist(center) / dist(home-flower),
        c = dot(center, home-flower) / dist(center) / dist(home-flower);
    if((c < 0.0f && d > 90.0f || c > 0.0f) && std::abs(s) < std::sin(M_PI / 360.0f * d) + EPS){
        return true;
    }
    return false;
}

int main(){
    while(std::cin >> H >> R, H || R){
        REP(i, H){
            double x, y;
            std::cin >> x >> y;

            hs[i].real(x); hs[i].imag(y);
        }

        std::cin >> U >> M >> S >> du >> dm >> ds;
        REP(i, U){
            double x, y;
            std::cin >> x >> y;

            us[i].real(x); us[i].imag(y);
        }
        REP(i, M){
            double x, y;
            std::cin >> x >> y;

            ms[i].real(x); ms[i].imag(y);
        }
        REP(i, S){
            double x, y;
            std::cin >> x >> y;

            ss[i].real(x); ss[i].imag(y);
        }

        P origin(0.0f, 0.0f);
        int counter[100];
        memset(counter, 0, sizeof(counter));
        REP(i, R){
            double x, y;
            std::cin >> x >> y;
            P wind(x, y);

            REP(k, H){
                bool f = can(hs[k], origin, du, wind),
                    g = true;

                REP(j, U){
                    g = g && !can(hs[k], us[j], du, wind);
                }
                REP(j, M){
                    g = g && !can(hs[k], ms[j], dm, wind);
                }
                REP(j, S){
                    g = g && !can(hs[k], ss[j], ds, wind);
                }

                if(f && g){counter[k] += 1;}
            }
        }

        int maxDays = 0;
        REP(i, H){
            maxDays = std::max(maxDays, counter[i]);
        }

        if(maxDays == 0){
            puts("NA");
        }else{
            std::vector<int> indices;
            REP(i, H){
                if(counter[i] == maxDays){indices.push_back(i+1);}
            }

            REP(i, (int)indices.size()){
                if(i == (int)indices.size() - 1){printf("%d\n", indices[i]);}
                else{printf("%d ", indices[i]);}
            }
        }
    }
}