POJ2165.Gunman

Posted sigongzi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2165.Gunman相关的知识,希望对你有一定的参考价值。

题解

把直线的斜率分解成二维,也就是随着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();
}

以上是关于POJ2165.Gunman的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

18.06.03 POJ 4126:DNA 15年程设期末05(状压DP)

poj 1011 sticks 解题。

贪心算法----区间覆盖问题(POJ2376)

POJ1699 Best Sequence(AC自动机+状压DP)

POJ-2752(KMP算法+前缀数组的应用)