您的位置:首页 > 其它

POJ 1755 判断线性区域是否存在可行区域

2017-09-27 20:56 288 查看

题意 : 给你每个人在每一段的速度,让你求出是否存在一种路程的安排使得这个人可以赢得这场比赛

题解 :可以去列方程组,然后发现是一个三维的变元,但是发现有一个变元,可以除过去就成了一个二元方程就是一个二维平面然后判断一个线性方程式组是否存在可行域.

发一个求线性区域的可行区域的模版

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps = 1e-16;
const double inf = 1e9 + 5;
const int maxn = 1505;
struct Point{
double x,y;
}p[maxn],tp[maxn],q[maxn];
struct Node{
double u,v,w;
}z[maxn];
double ab (double x) {return x > 0 ? x : -x;}
double xmul(Point p0,Point p1,Point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
Point Intersection(Point p1,Point p2,double a,double b,double c){
double u = ab(a*p1.x+b*p1.y+c);
double v = ab(a*p2.x+b*p2.y+c);
Point t;
t.x=(p1.x*v+p2.x*u)/(u+v);t.y=(p1.y*v+p2.y*u)/(u+v);
return t;
}
double Get_area(Point p[],int n){
double area=0;
for(int i=2;i<n;i++)
area+=xmul(p[1],p[i],p[i+1]);
return -area/2.0;
}
void Cut(double a,double b,double c,Point p[],int &cnt){
int tmp=0;
for (int i=1;i <= cnt;i++){
if(a*p[i].x+b*p[i].y+c>-eps) tp[++tmp]=p[i];
else{
if(a*p[i-1].x+b*p[i-1].y+c>eps)
tp[++tmp]=Intersection(p[i-1],p[i],a,b,c);
if(a*p[i+1].x+b*p[i+1].y+c>eps)
tp[++tmp]=Intersection(p[i],p[i+1],a,b,c);
}
}
for(int i=1;i<=tmp;i++)
p[i]=tp[i];
p[0]=p[tmp];p[tmp+1]=p[1];
cnt=tmp;
}
int slove(int n,int idx) {
p[1].x=0;p[1].y=0;
p[2].x=0;p[2].y=inf;
p[3].x=inf;p[3].y=inf;
p[4].x=inf;p[4].y=0;
p[0]=p[4];p[5]=p[1];
int cnt=4;
for(int i=0;i<n;i++){
if(i==idx) continue;
double a,b,c;
a=(z[idx].u-z[i].u)/(z[idx].u*z[i].u);
b=(z[idx].v-z[i].v)/(z[idx].v*z[i].v);
c=(z[idx].w-z[i].w)/(z[idx].w*z[i].w);
if(a==0 && b==0&&c<eps) return 0;
Cut(a,b,c,p,cnt);
}
return ab (Get_area(p, cnt)) >= eps;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++)
scanf("%lf%lf%lf",&z[i].u,&z[i].v,&z[i].w);
for(int i=0;i<n;i++)
puts(slove(n,i)?"Yes":"No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 计算几何