重慶部門ACMウォームアップの質問8531. KDの恐怖
フロントブロガーはまず、すべての参照、にジオメトリ質問の内側にあるプログラミングの問題を解決については、この通路には、以下のボー主に解決される問題により、このウォームアップマッチ最低レートに提出する私たちのベクターが使用されているACMグループ、バイナリ方法;顕著な点がポイントとラインの関係で、私はそれが中学・高校十分の知識を持っていると思いますが、実際には、それほど深いがあることができ、この多国間のライン内にある
ああ、Haは話題に言わなかった、それは単純に、このトピックを意味し、これは、ポイントが多角形内にあるか否かを判断する内部機構です。
- :まず第一に、我々は、このチャートを見てください
私たちは、ハに事実を参照してください、私たちは、あなただけの行に同じ側に多角形の各辺に合わせていることをMポイントを確保する必要がある(ボス座標)Mポイントは、凸多角形の実際の内側にあることをことを確実にしたいです我々は→Bへの我々の開始点Aは最初、私たちのビューのMポイントのこちら側の左側ABであるので、これは確実にするためであるので、その入力が反時計回りであることを確認するための入力としてカザフスタンを見ている他のすべての点M凸多角形の点Mの左側を確保します。私たちは、それが0より大きい場合、この値と0との間の関係を見るための方程式になる。この点にあるような直線の方程式はどうか、この線上の点や、この行を右または左を決定するために、を認識している学びましたすなわち、この線の左側にゼロ未満である、行の右側に点であり、それはこのライン上のゼロに等しいです。
物事を構成するこのロジックを持ちます。我々は線形方程式を決定することができる2つの点は、我々がされるまで、最初の点と2つのドット式、二点及び組成式、三点及び式の組成の第四点の第三の点を使用し......最初の8つの点と最初のポイントは、我々は方程式を作ります。
そのための式を決定するために2つの時の式は、
(Y1-Y2)* X- +(X1-X2)Y- * - (Y1-Y2)*×1 +(X1-X2)*、Y1 = 0
私たちは聞かせて:
A =(Y1 -Y2)
B =(X1-X2)
C =(X1-X2)Y1 * - (Y1-Y2)* X1
これは、それぞれ両面を格納するための二次元アレイの方程式のための私の名前の後ろに計算して検証を容易にしますA、B、Cの値の
コード:
public static void etl(ArrayList<String[]> D) {
for(int i=1;i<D.size();i++) {
double a,b,c;
if(i == 8) {
a = Integer.parseInt(D.get(i)[2]) -Integer.parseInt(D.get(1)[1]);
b= Integer.parseInt(D.get(i)[1]) -Integer.parseInt(D.get(0)[1]);
c = b*Integer.parseInt(D.get(i)[2]) -a*Integer.parseInt(D.get(i)[1]);
}
else {
a = Integer.parseInt(D.get(i)[2]) -Integer.parseInt(D.get(i+1)[2]);
b= Integer.parseInt(D.get(i)[1]) -Integer.parseInt(D.get(i+1)[1]);
c = b*Integer.parseInt(D.get(i)[2]) -a*Integer.parseInt(D.get(i)[1]);
}
equation[i-1][0] = a;
equation[i-1][1] = b;
equation[i-1][2] = c;
vector[i-1][0] = -a;
vector[i-1][1] = -b;
}
}
私は判断といえば、この質問は、凸多角形の判断は非常に各辺のベクトルのベクトルを格納するために2次元配列を定義したかどうかである必要があり、明らかにこの質問が使用されていないと思った、または言及しているのでコードの最後の直接の外観に直接スキップすることができます興味を持っていない場合は凸多角形の方法にするかどうか、もっと勉強した後、良いです。
ここでは凸多角形のアプローチがあるかどうかを判断する
最も可能性の高い人は360度の凸多角形の外装角の方法を考えさせるために、ここでは不可能である我々のプログラムでの使用に明らかにされ、あまりにも計算集約こと、および三角形を含み、余弦置換の法則の正弦逆三角関数は、我々はベクトル解析の方法の別の方法を使用することを明らかに非現実的であり、
この方法は非常に単純な原理は似ても、我々は最初のAB・BC(内積を注意ベクトルを使用します代わり×乗算)我々はそれが私たちと一緒に使用される値の値を取得し、ベクトル積が0であれば、我々は、すべてのおなじみの0を比較している、それは、この垂直二つのベクトルが、それは2つのベクトルのゼロより大きいクリップがあることを示し、未満の幾何学的図形を関係ベクトルの角度で見つけることができ、90度以上の角度が90度未満次にポリゴンは、180度に等しい多角形の角に相補的である90度の角度よりも大きくなっている-のベクトルの間の角度度
良好な関係で、私たちは、すべてのベクトル積は、多角形が凸であることを確認するために、ゼロよりも大きいことを保証するために、最後の要素とゼロとの関係で判断の組み合わせのベクトル積の最初の要素いったん横断ベクトルの配列を判断することができます。
ここにあります私の全体のプログラムコード:
package proje_1;
import java.util.ArrayList;
import java.util.Scanner;
class acm_9 {
private static double[][] vector = new double[8][2];
private static double[][] equation = new double[8][3];
public static ArrayList<String[]> input(){
Scanner scanner = new Scanner(System.in);
ArrayList<String[]> data = new ArrayList<String[]>();
for(int i = 0;i<9;i++) {
String[] point = scanner.nextLine().split(" ");
data.add(point);
}
return data;
}
public static void etl(ArrayList<String[]> D) {
for(int i=1;i<D.size();i++) {
double a,b,c;
if(i == 8) {
a = Integer.parseInt(D.get(i)[2]) -Integer.parseInt(D.get(1)[1]);
b= Integer.parseInt(D.get(i)[1]) -Integer.parseInt(D.get(0)[1]);
c = b*Integer.parseInt(D.get(i)[2]) -a*Integer.parseInt(D.get(i)[1]);
}
else {
a = Integer.parseInt(D.get(i)[2]) -Integer.parseInt(D.get(i+1)[2]);
b= Integer.parseInt(D.get(i)[1]) -Integer.parseInt(D.get(i+1)[1]);
c = b*Integer.parseInt(D.get(i)[2]) -a*Integer.parseInt(D.get(i)[1]);
}
equation[i-1][0] = a;
equation[i-1][1] = b;
equation[i-1][2] = c;
vector[i-1][0] = -a;
vector[i-1][1] = -b;
}
}
public static boolean judge(double x,double y) {
for(int i =0 ;i<equation.length;i++) {
if(equation[i][0]*x + equation[i][1]*y + equation[i][2] >= 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
ArrayList<String[]> data = input();
etl(data);
if(judge(Integer.parseInt(data.get(0)[0]), Integer.parseInt(data.get(0)[1]))) {
System.out.println("WTF!");
}
}
}