题意: 求一条线段上的点到其他m个点有多少个最短距离, m个点中没有两点到线段上的端点距离相等~
分析:用一个点和其他点的中垂线所在的半平面划分该点所在的区域, 该区域内任意一个点的距离到该点相对其他点距离最近.
具体实现:用一个足够大的矩形覆盖所有点, 然后划分区域, 最后判断所问线段和多少个区域(凸包)有交点~
分析:用一个点和其他点的中垂线所在的半平面划分该点所在的区域, 该区域内任意一个点的距离到该点相对其他点距离最近.
具体实现:用一个足够大的矩形覆盖所有点, 然后划分区域, 最后判断所问线段和多少个区域(凸包)有交点~
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#define FOR(i, n) for(int i = 0; i < n; i++)
#define MEM(array) memset(array, 0, sizeof(array))
#define eps 1e-7
#define INF (int)1e5
#define PI acos(-1.0)
#define MAX 111
using namespace std;
inline int sgn(const double &x){return x > eps ? 1 : (x < -eps ? -1 : 0);}
inline double sqr(const double &x){return x * x;}
struct Point {
double x, y;
Point() {}
Point(const double &xx, const double &yy):x(xx), y(yy) {}
friend Point operator + (const Point &b, const Point &a) {
return Point(b.x + a.x, b.y + a.y);
}
friend Point operator - (const Point &b, const Point &a) {
return Point(b.x - a.x, b.y - a.y);
}
Point operator * (const double &a)const{
return Point(x * a, y * a);
}
Point operator / (const double &a) const{
return Point(x / a, y / a);
}
friend double dot(const Point &a, const Point &b) {
return a.x *b.x + a.y * b.y;
}
friend double det(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
double len( )const {
return sqrt(dot(*this, *this));
}
bool operator < (const Point &a)const {
return sgn(x - a.x) < 0 || (sgn(x - a.x) == 0 && sgn(y - a.y) > 0);
}
bool operator == (const Point &a)const {
return sgn(x - a.x ) == 0 && sgn(y - a.y) == 0;
}
Point rotate(const double &angle)const{
double x1 = x * cos(angle) - y * sin(angle);
double y1 = x * sin(angle) + y * cos(angle);
return Point(x1, y1);
}
void in() {
scanf("%lf %lf", &x, &y);
}
void out()const {
printf("%.4f %.4f\n", x, y);
}
}c[MAX], b[MAX];
int n, m;
struct Line{
Point s, t;
Line(){}
Line(const Point &ss, const Point &tt):s(ss), t(tt){}
//获取s t的中垂线的s所在的半平面线(左边)
friend void getPlaneLine(const Line &line, Line &res){
Point mid = (line.s + line.t)/ 2;
Point fa = line.dir().rotate(PI / 2);
res = Line(mid, mid + fa);
}
//线段和直线
friend bool lineInsectLinevEx(const Line &l1, const Line &lv, Point &res){
int res1 = sgn( det(l1.s - lv.s, lv.t - lv.s) );
int res2 = sgn( det(l1.t - lv.s, lv.t - lv.s) );
if(res1 * res2 < 0){
double s1 = det(l1.s - lv.s, lv.dir()), s2 = det(l1.t - lv.s, lv.dir());
res = (l1.t * s1 - l1.s * s2 ) /(s1 - s2);
return 1;
}
return 0;
}
//线段和线段, 不包含端点
friend bool lineInsectLineEx(const Line &l1, const Line &l2){
int res1 = sgn( det(l1.s - l2.s, l2.t - l2.s) * det( l1.t - l2.s, l2.t - l2.s) ) ;
int res2 = sgn( det(l2.s - l1.s, l1.t - l1.s) * det( l2.t - l1.s, l1.t - l1.s) ) ;
return res1 < 0 && res2 < 0;
}
Point dir()const{
return t - s;
}
void out()const{
s.out();
t.out();
}
};
struct Poly{
vector<Point> p;
friend Poly getCut(const Poly &poly, const Line &line){
int tn = poly.p.size();
Poly resp;
for(int i = 0; i < tn; i++){
Point va = poly.p[i] - line.s, vb = line.dir();
int res = sgn(det(va, vb));
if(res <= 0){//in half
resp.p.push_back(poly.p[i]);
}else {
int j = i - 1, k = i + 1;
if(j < 0)j = tn - 1;
if(k > tn - 1)k = 0;
int id[] = {j, k};
FOR(kk, 2){
va = poly.p[id[kk]] - line.s;
res = sgn(det(va, vb) );
Point ins;
Line l1(poly.p[i], poly.p[id[kk]]);
if(res < 0 && lineInsectLinevEx( l1, line, ins)){
resp.p.push_back(ins);
}
}
}
}
return resp;
}
//和线段的是否有交,不包含端点
bool isInsectLineEx(const Line &l1){
if(isContain(l1.s) == true || isContain(l1.t) == true)return true;
int tn = p.size();
for(int i = 0; i < tn; i++){
Line lv(p[i], p[(i + 1)%tn]);
if(lineInsectLineEx(lv, l1))return true;
}
return false;
}
bool isContain(const Point &t){
int sign = 0;
int tn = p.size();
for(int i = 0; i < tn; i++){
int signt = sgn( det( p[i] - t, p[(i + 1)%tn] - t) );
if(signt){
if(sign){
if(sign != signt )return 0;
}else {
sign = signt;
}
}else
return 0;
}
return 1;
}
}poly[MAX], rect;
void init(){
FOR(i, n){
c[i].in();
}
FOR(j, m){
b[j].in();
}
}
void getPoly(){
FOR(i, m){
Poly cur = rect;
FOR(j, m){
if(j == i)continue;
Line line(b[i], b[j]), res;
getPlaneLine(line, res);
// res.out();
cur = getCut(cur, res);
}
poly[i] = cur;
}
}
bool v[MAX];
int judge(int a, int b){
int ans = 0;
memset(v, 0, sizeof(v));
// for(int i = a; i < b; i++)太二不能多说
{
for(int j = 0; j < m; j++){
if(poly[j].isInsectLineEx(Line(c[a], c[b]))){
v[j] = 1;
}
}
}
for(int i = 0; i < m; i++){
if(v[i])ans ++, v[i] = 0;
}
return ans - 1;
}
void solve(){
int k ,a, b;
cin>>k;
while(k--){
cin>>a>>b;
cout<<judge(a - 1, b - 1)<<endl;
}
}
int main()
{
rect.p.push_back(Point(-INF, -INF));
rect.p.push_back(Point(INF, -INF));
rect.p.push_back(Point(INF, INF));
rect.p.push_back(Point(-INF, INF));
while(cin>>n>>m){
init();
getPoly();
solve();
}
return 0;
}
/*
*/