1086 - あなたはジオメトリの問題あまりにHDUを解決することができます

多くのジオメトリー(几何)の問題は、ACM / ICPCに設計されていました。そして今、私はまた、この最終試験のための幾何学の問題を準備します。多くのACMersの経験によると、幾何学的な問題は、常に多くの問題ですが、この問題は、私たちが今、試験に参加しているすべてのではなく、コンテストが:)の後に、非常に簡単です 
、あなたにNを与える(1 <= N <= 100)のセグメント(线段)、全ての交点の数(交点)出力をしてください。M(M> 2)セグメントが同じ点で交わる場合は繰り返しカウントする必要があります。 

注意: 
次の2つのセグメントが複数の箇所で交差しないことを前提とすることができます。 

入力

入力は複数のテストケースが含まれています。各テストケースは、最初の行に整数Nを(1 = N <= 100)が含まれ、そして次にNラインが従います。各行は4台のフロートと一つのセグメントは、セグメントの終点の座標であるX1、Y1、X2、Y2値について説明します。 
0から始まるテストケースは、入力を終了し、このテストケースは、処理されるべきではありません。 

出力

各場合について、交差点の数、1つのライン一つのケースを印刷します。 

サンプル入力

2
0.00 0.00 1.00 1.00
0.00 1.00 1.00 0.00
3
0.00 0.00 1.00 1.00
0.00 1.00 1.00 0.000
0.00 0.00 1.00 0.00
0

サンプル出力

1
3

 二つのセグメントのバナナかどうかを確認する方法?

まず、あなたが知っておく必要があります。

チキン完全な説明!https://www.cnblogs.com/tuyang1129/p/9390376.html

以下は----------->外積です

(ベクトル)AX(ベクトル)B <0 ------> Bの時計回りの回転

(ベクトル)AX(ベクトル)B = 0 ------> 平行とB!

(ベクトル)AX(ベクトル)B> 0 ------> AはBを与えるために反時計回りに回転されます

第二に、あなたが考えることができます。

http://blog.sina.com.cn/s/blog_b2ad877f0102witj.html

                           AEAE・å¤æ线æ®μç¸äº¤

 まず、我々は2行は重複部分が存在しない場合は精力的な、偶然の一部ではないんではない矩形場所を決定する必要があります。左上記の場合のように。限り、二つの長方形の試験領域が重ならないように、2つのセグメントが直接交差することなく決定することができます。矩形枠部と交差点ではなく、十分な条件のために必要な条件が重なりがある、しかし、すなわち、2本の線分の交点を有していてもよく、または、上記及び図1の右側のように、交差部を有していなくてもよいです。私たちの主な仕事は、この2つの場合を区別することです。

図のために、我々は、P1、およびP2点直線Q1Q2のいずれかの側に(青色のドット)、およびQ1とQ2(赤い点)直線P1P2の同じ側の点を発見しました。点Q1とQ2は、直線P1P2、P2と直線Q1Q2の両側の2点の右側にされています。

要約すると、2つの条件が、セグメントバナナのために必要かつ十分である2つの他の線分の両側にライン内の任意の2点!(ここで、ベクトルの重要性は、排他的な交換位置番号の他、2つのベクトルのクロス積の結果に対して反対方向を結ぶベクトルであります!!)

 

#include<iostream>
using namespace std;
struct point
{
    double x,y;
}p[101];
double mult_cross(point a, point b, point c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
bool ifcross(point a,point b,point c,point d)
{
    if(mult_cross(c, b, a)*mult_cross(b, d, a)<0)return false;
    if(mult_cross(a, d, c)*mult_cross(d, b, c)<0)return false;
    if(max(a.x,b.x)<min(c.x,d.x))return false;
    if(max(a.y,b.y)<min(c.y,d.y))return false;
    if(max(c.x,d.x)<min(a.x,b.x))return false;
    if(max(c.y,d.y)<min(a.y,b.y))return false;
    return true;
}
int main()
{
    int n;
    while(cin>>n&&n)
    {
        int sd=1;
        for(int i=1; i<=n; i++)
        {
            cin>>p[sd].x>>p[sd].y>>p[sd+1].x>>p[sd+1].y;
            sd+=2;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(ifcross(p[2*i-1],p[2*i],p[2*j-1],p[2*j]))
                ans++;
            }
        }
       cout <<ans<<endl;
    }
}

 

おすすめ

転載: blog.csdn.net/qq_43813697/article/details/90519863
おすすめ