计算几何 ICPC昆明

计算几何

添加链接描述

code

 #include<bits/stdc++.h>
 using namespace std;
 typedef pair<double, double> pii;
 const int N = 1010;
 const double inf = 1e18;
 const double eps = 1e-8;
 int n, m;
 double xs, ys, xt, yt, x[N], y[N]; 
 int sgn (double x) 
 {
    if(fabs(x) < eps) 
        return 0;
    else if(x < 0) 
        return -1;
    else
        return 1;
 }
vector<pii> p[N];
//求直线(x1, y1),(x2, y2)和直线(x3, y3),(x4, y4)的坐标,返回一个坐标
pii ver (double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
    if (x1 == x2 && y1 == y2) 
        return make_pair(inf, inf);
    double k1 = (x1 == x2 ? inf : (y1-y2) / (x1-x2));
    double k2 = (x3 == x4 ? inf : (y3-y4) / (x3-x4));
    if (sgn(k1 - k2) == 0) 
        return make_pair(inf, inf);
    if (k1 == inf)
        return make_pair(x1, x1 * k2 + y3 - k2 * x3);
    else if(k2 == inf)
        return make_pair(1.0*(y1 - y3 + k2 * x3)/k2, y1);
    double b1 = y1 - k1 * x1;
    double b2 = y3 - k2 * x3;
    double x = (b2 - b1) / (k1 - k2);
    double y = k1 * x + b1;
    return make_pair(x, y);
 }
int cmp(pii x, pii y) 
{
    if (sgn(x.first - y.first) != 0)
        return sgn(x.first - y.first) < 0;
    else 
        return sgn(x.second - y.second) < 0;
} 
int cmp1(pii x, pii y) 
{
    if (sgn(x.first - y.first) != 0)
        return sgn(x.first - y.first) > 0;
    else 
        return sgn(x.second - y.second) > 0;
} 
int main () 
{
    cin >> n >> m >> xs >> ys >> xt >> yt;
    for(int i = 1; i <= n; i++)
        cin >> x[i] >> y[i];
    for (int i = 1; i <= n; i++) 
    {
        for (int j = 1; j <= n; j++) 
        {
            if (i == j) 
                continue;
            pii it=ver(x[i], y[i], x[j], y[j], xs, ys, xt, yt); 
            if (it.first == inf) 
                continue;//没有交点
            if (sgn(it.first-min(xs,xt))<0||sgn(it.first-max(xs,xt))>0||sgn(it.second-min(ys,yt))<0||sgn(it.second-max(ys,yt))>0) 
                continue;//交点在线段以外
            p[i].push_back(it); 
        }
        if(xs < xt) 
            sort(p[i].begin(), p[i].end(), cmp);
        else if(xs > xt) 
            sort(p[i].begin(), p[i].end(), cmp1);
        else if(ys < yt) 
            sort(p[i].begin(), p[i].end(), cmp);
        else 
            sort(p[i].begin(), p[i].end(), cmp1);
    }
    while(m--) 
    {
        int h, t;
        cin >> h >> t;
        if(t > p[h].size()) 
        {
            printf("-1\n");
            continue;
        }
        printf("%.10f %.10f\n",p[h][t-1].first, p[h][t-1].second);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值