AOJ : 1266 - How I Wonder What You Are!
問題概要
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1266
複数の星の座標が(x,y,z)で与えられます。
自分が所持している望遠鏡を使用して、それらの星の内、何個見ることができるかどうかを答える問題です。
望遠鏡を複数個もっていて、使用する望遠鏡によって観れる方向と範囲が変化します。
望遠鏡で見える範囲は、入力では
- x y z phi
の順で与えられます。
(x,y,z)の方向のベクトルとphiの角度をなす円錐の形をした範囲が望遠鏡で見える範囲です。(問題の図を見ればわかります)
アルゴリズム
高校数学を覚えているかどうかの問題です。
星と望遠鏡を一つずつ選び、それらのベクトルの内積をとって、次の公式に当てはめて計算します。
ベクトルのなす角
この公式で得られた解が、望遠鏡のphi以下であれば星を見ることができる、ということになります。
あとは、これを二重ループでまわすだけです。
プログラム
#include <stdio.h> #include <math.h> #define EPS 1e-10 #define rep(i,n) for(i=0;i<n;i++) typedef struct{ double x,y,z; }P; double dot(P a,P b){ return a.x * b.x + a.y * b.y + a.z * b.z; } double dist(P a){ return sqrt(a.x*a.x + a.y*a.y + a.z*a.z); } double getTheta(P a,P b){ return acos(dot(a,b) / (dist(a) * dist(b))); } int main(void){ int i,j; int n,m,ans; double phi[50]; P s[500],t[50]; while(scanf("%d",&n) && n){ rep(i,n) scanf("%lf%lf%lf",&s[i].x,&s[i].y,&s[i].z); scanf("%d",&m); rep(i,m) scanf("%lf%lf%lf%lf",&t[i].x,&t[i].y,&t[i].z,&phi[i]); ans = 0; rep(i,n)rep(j,m){ if(getTheta(s[i],t[j]) < phi[j] + EPS){ ans++; break; } } printf("%d\n",ans); } return 0; }