1. 程式人生 > >[poj] 1066 Treasure Hunt || 判斷直線相交

[poj] 1066 Treasure Hunt || 判斷直線相交

ref problem 兩個 cst puts efi 連線 mark point

原題

在金字塔內有一個寶藏p(x,y),現在要取出這個寶藏。
在金字塔內有許多墻,為了進入寶藏所在的房間必須把墻炸開,但是炸墻只能炸每個房間墻的中點。
求將寶藏運出城堡所需要的最小炸墻數。


判斷點和直線相交。
枚舉每道墻的兩個端點和p的連線這條線段和墻的交點的次數最小值即為需要炸墻的最小次數。
【註意當墻數為零時輸出1;】

#include<cstdio>
#include<algorithm>
#define N 33
using namespace std;
int ans=0x3f3f3f3f,n;
struct point
{
    double x,y;
    point() {}
    point(double
_x,double _y) : x(_x),y(_y) {} point operator - (const point &b) const { return point(b.x-x,b.y-y); } double operator * (const point &b) const { return x*b.y-b.x*y; } bool operator == (const point &b) const { return x==b.x && y==b.y; } }p[2
*N],end; int intersect(point a,point b)//相交 { int ans=0; if (a==b) return 0; for (int i=1;i<=n;i++) if (((a-p[i])*(a-b))*((a-p[i+n])*(a-b))<=0 && (p[i]-a)*(p[i]-p[i+n])*((p[i]-b)*(p[i]-p[i+n]))<=0) ans++; return ans; } int main() { scanf("%d",&n); for
(int i=1;i<=n;i++) scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y); scanf("%lf%lf",&end.x,&end.y); if (!n) { puts("Number of doors = 1"); return 0; } for (int i=1;i<=2*n;i++) ans=min(ans,intersect(p[i],end)); printf("Number of doors = %d\n",ans); return 0; }

[poj] 1066 Treasure Hunt || 判斷直線相交