UVa11030-Predator II

本文介绍了一个迷宫穿越问题,目标是最少跨越障碍达到终点。利用计算机算法,通过判断点是否在多边形内部来计算最少跨越次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem D

Predator II

Time limit: 2 seconds

 

Oh No!!! The predator has entered the room again. But this time it is a different kind of room.

The room is a square of size 10000 X 10000. There are several compartments of different shapes and sizes, situated strictly inside the room. The walls of different compartments don’t overlap, but a compartment can be completely inside that of another.

 

This time the predator has learned to hop over walls, but it can jump over at most one wall at a time. Given the starting and ending coordinates of the predator, and the positions of the compartments, your job is to find out the minimum number of hops required for the predator to reach his destination from the start.

 

The starting and ending positions are never on the boundary of any compartment.

 

Input

 

The first line of input is an integer (T ≤ 20), that indicates the number of test cases. Each case starts with an integer

(n ≤ 20), that determines the number of compartments in the room. The next n lines give the positions of the compartments. The compartments are simple polygons. The description of each compartment starts with an integers (S ≤ 10), that gives the number of sides of the polygon, followed by pairs of x, y coordinates in order. Next there is an integer that determines the number of queries for this scenario. Each of the next Q lines contains 4 integers x1, y1, x2, y2(x1, y1) is the starting position and (x2, y2) is the ending position.

 

The lower left and upper right coordinates of the room are (0, 0) and (10000, 10000) respectively.

 

Output

 

For each case, output the case number. Then for each query, output the minimum number of hops required.

 

Sample Input

Output for Sample Input

2

3

4 1 1 5 1 5 5 1 5

4 2 2 4 2 4 4 2 4

3 7 7 10 10 7 10

1

3 3 8 9

1

4 1 1 10 1 10 10 1 10

2

2 2 100 100

100 100 2 2

Case 1:

3

Case 2:

1

1

 

 

ProblemSetter: Sohel Hafiz

Next Generation Contest 2

 

Illustration

The following diagram depicts the first sample input.

 

 

Pink spot à starting position

Black spot à target

The three hops are shown by three broad line segments.

 

题目大意就是有 n个polygon, m组询问,每次询问一个点最少要越过多少条边才能到达另一个点, 用容斥可以解决  包括a点的polygon数量+b点的polygon数量-2*(同时包括a,b的polygon数量)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const double eps = 1e-8;
struct Point{
    double x,y;
    friend bool operator < (Point a,Point b){
        if(fabs(a.x-b.x)>eps) return a.x < b.x;
        else return a.y < b.y;
    }
    friend bool operator == (Point a,Point b){
        return fabs(a.x-b.x)<eps && fabs(a.y-b.y)<eps;
    }
    Point(double x=0,double y=0):x(x),y(y){}
};
Point operator - (const Point &a,const Point &b){
    return Point(a.x-b.x,a.y-b.y);
}
int dcmp(double x){
    if(fabs(x) < eps) return 0;
    else if(x > 0) return 1;
    else return -1;
}
double det(Point p1,Point p2){
    return p1.x*p2.y-p1.y*p2.x;
}
int inPolygon(vector<Point> p, Point q) {
    int cnt = 0;
    int n = p.size();
    for(int i = 0, j = n-1; i < n; j = i++) {
        if(p[i].y > q.y != p[j].y > q.y &&
           q.x < (p[j].x-p[i].x)*(q.y-p[i].y)/(p[j].y-p[i].y) + p[i].x)
           cnt++;
    }
    return cnt&1;
}
int n;
vector<vector<Point> > vp;
int main(){

    int ncase,T=1;
    cin >> ncase;
    while(ncase--){
        cin >> n;
        vp.clear();
        for(int i = 0; i < n; i++){
            vector<Point> t;
            t.clear();
            int m;
            cin >> m;
            for(int k = 0; k < m; k++){
                double x,y;
                cin >> x >> y;
                t.push_back(Point(x,y));
            }
            vp.push_back(t);
        }
        int fd;
        cin >> fd;
        printf("Case %d:\n",T++);
        while(fd--){
            int a=0,b=0,c=0;
            double x,y;
            cin >> x >> y;
            Point t1(x,y);
            cin >> x >> y;
            Point t2(x,y);
            for(int i = 0; i < n; i++){
                int flag1 = inPolygon(vp[i],t1),flag2 = inPolygon(vp[i],t2);
                if(flag1)
                    a++;
                if(flag2)
                    b++;
                if(flag1&&flag2) c++;
            }
            cout<<a+b-2*c<<endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值