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]);} } } } }