1. 程式人生 > >【POJ】2165.Gunman

【POJ】2165.Gunman

goto tmp for open pen std flag cst ble

題解

把直線的斜率分解成二維,也就是隨著z的增加x的增量和y的增量
我們發現一條合法直線向上移一點一定能碰到一條橫線
知道了這條橫線可以算出y的斜率
我們旋轉一下,讓這條橫線碰到兩條豎線,就可以算出x的斜率,進而判斷直線在不在平面內

代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
//#define ivorysi
#define MAXN 105
#define eps 1e-8
using namespace std;
typedef long
long int64; typedef double db; struct plane{ double x[2],y[2],z; }pl[MAXN]; struct Point{ double x,y; }P[MAXN * 4]; int N,cnt; db yk,xk,sx; void Init() { scanf("%d",&N); for(int i = 1 ; i <= N ; ++i) { scanf("%lf%lf%lf%lf%lf",&pl[i].x[0],&pl[i].y[0],&pl[i].x[1],&pl[i].y[1
],&pl[i].z); } } void Solve() { for(int i = 1 ; i <= N ; ++i) { for(int r = 0 ; r <= 1 ; ++r) { db k = pl[i].y[r] / pl[i].z; cnt = 0; bool flag = 0; for(int j = 1 ; j <= N ; ++j) { if(pl[j].z * k > pl[j].y[1] + eps || pl[j].z * k < pl[j].y[0
] - eps) goto succ; for(int c = 0 ; c <= 1 ; ++c) { P[++cnt] = (Point){pl[j].x[c],pl[j].z}; } } yk = k; for(int j = 1 ; j <= cnt ; ++j) { for(int h = j + 1 ; h <= cnt ; ++h) { if(P[j].y == P[h].y) continue; flag = 1; k = (P[j].x - P[h].x) / (P[j].y - P[h].y); if(P[j].x == P[h].x) k = 0; sx = P[j].x - P[j].y * k; for(int l = 1 ; l <= N ; ++l) { db tmp = sx + k * pl[l].z; if(tmp < pl[l].x[0] - eps || tmp > pl[l].x[1] + eps) {flag = 0;break;} } if(flag) { xk = k;goto succ; } } } succ:; if(flag) { puts("SOLUTION"); printf("%.6f\n",sx); for(int i = 1 ; i <= N ; ++i) { printf("%.6f %.6f %.6f\n",sx + xk * pl[i].z,yk * pl[i].z,pl[i].z); } return; } } } puts("UNSOLVABLE"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }

【POJ】2165.Gunman