ACM-ICPC北京赛区2017网络同步赛G

http://hihocoder.com/contest/icpcbeijing2017/problem/7

bfs+计算几何

难点是线段与三角形的关系,有3种情况 1. 线段2端点都在三角形外,判断线段与三角形3条边是否规范相交 2.线段一个端点在三角形内或上,另一个在三角形外,两个点靠近一点点,再判是否在三角形内3.两个点都在三角形内或上,看中点是否在三角形内

计算几何还是菜啊

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pi;
const int maxn = 29;
char mapp[maxn][maxn];
int dir[8][2] = {1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
int n;
const double eps = 1e-6;
struct Point{
    double x,y;
    Point operator -(const Point&a){
        return {x-a.x,y-a.y};
    }
    Point operator +(const Point&a){
        return {x+a.x,y+a.y};
    }
    double operator *(const Point&a){
        return x*a.x+y*a.y;
    }
    Point operator *(const double  &a){
        return {x*a,y*a};
    }
    double operator ^(const Point&a){
        return x*a.y-y*a.x;
    }

};
int sig(double x){
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
double multi(Point p1,Point p2,Point base){
    Point v1 = p1-base;
    Point v2 = p2-base;
    return v1^v2;
}
bool onseg(Point a,Point b,Point now){
    if(now.x<=max(a.x,b.x) && now.x>=min(a.x,b.x) && now.y<=max(a.y,b.y)
       && now.y>=min(a.y,b.y) && sig(multi(b,now,a))==0) return true;
    return false;
}
bool intrangle(Point a,Point b,Point c,Point now){
    int sig1 = sig(multi(now,b,a));
    int sig2 = sig(multi(now,c,b));
    int sig3 = sig(multi(now,a,c));
    if(sig1==1 && sig2==1 && sig3==1) return true;
    if(sig1==-1 && sig2==-1 && sig3==-1) return true;
    return false;
}
bool intrangleOrOnSeg(Point a,Point b,Point c,Point now){
    int sig1 = sig(multi(now,b,a));
    int sig2 = sig(multi(now,c,b));
    int sig3 = sig(multi(now,a,c));
    if(sig1==1 && sig2==1 && sig3==1) return true;
    if(sig1==-1 && sig2==-1 && sig3==-1) return true;
    if(onseg(a,b,now)) return true;
    if(onseg(c,b,now)) return true;
    if(onseg(a,c,now)) return true;
    return false;
}
Point trangle[10];
int vis[maxn][maxn];
int step[maxn][maxn];
queue<pi> q;
bool kp(Point a,Point b,Point c,Point d){
    if(min(a.x,b.x)<=max(c.x,d.x) &&
       min(c.x,d.x)<=max(a.x,b.x) &&
       min(a.y,b.y)<=max(c.y,d.y) &&
       min(c.y,d.y)<=max(a.y,b.y) ) return true;
    return false;
}
bool kl(Point a,Point b,Point c,Point d){
    double tv1 = multi(c,d,a);
    double tv2 = multi(c,d,b);
    double tv3 = multi(a,b,c);
    double tv4 = multi(a,b,d);
    if(sig(tv1*tv2)<0 && sig(tv3*tv4)<0) return true;
    return false;
}
bool gfxj(Point a,Point b,Point c,Point d){
    if(kp(a,b,c,d) && kl(a,b,c,d)) return true;
    return false;
}
Point mov(Point base,Point vec,double ra){
    Point tmp = vec*ra;
    return base+tmp;
}
bool check(Point la,Point lb){
    int in = 0;
    if(intrangleOrOnSeg(trangle[0],trangle[1],trangle[2],la)) in++;
    if(intrangleOrOnSeg(trangle[0],trangle[1],trangle[2],lb)) in++;
    if(in==0) {
        if(gfxj(trangle[0],trangle[1],la,lb)) return true;
        if(gfxj(trangle[2],trangle[1],la,lb)) return true;
        if(gfxj(trangle[0],trangle[2],la,lb)) return true;
        return false;
    }else if(in==2){
        Point mid = {(la.x+lb.x)/2,(la.y+lb.y)/2};
        if(intrangle(trangle[0],trangle[1],trangle[2],mid)) return true;
        return false;
    }else{
        Point tmp1 = mov(la,lb-la,0.01);
        Point tmp2 = mov(lb,la-lb,0.01);
        if(intrangle(trangle[0],trangle[1],trangle[2],tmp1))return true;
        if(intrangle(trangle[0],trangle[1],trangle[2],tmp2))return true;
        return false;
    }
}
int bfs(){
    memset(vis,0,sizeof(vis));
    vis[0][0] = 1;
    while(!q.empty()){q.pop();}
    q.push(pi(0,0));
    while(!q.empty()){
        pi now = q.front();
        q.pop();
        if(now.first==n-1 && now.second==n-1) return step[now.first][now.second];
        for(int i=0;i<8;i++){
            int tx = now.first+dir[i][0];
            int ty = now.second+dir[i][1];
            if(tx<0 || tx>=n) continue;
            if(ty<0 || ty>=n) continue;
            if(vis[tx][ty]==1 || mapp[tx][ty]=='#') continue;
            if(check({ty,tx},{now.second,now.first})) continue;
            vis[tx][ty] = 1;
            step[tx][ty] = step[now.first][now.second]+1;
            q.push(pi(tx,ty));
        }
    }
    return -1;
}
int main()
{
    //cout<< onseg({0,0},{1,1},{0.999,0.999})<<endl;
    while(~scanf("%d",&n)){
        for(int i=0;i<3;i++){
            double tx,ty;
            scanf("%lf%lf",&tx,&ty);
            trangle[i] = {tx,ty};
        }
        for(int i=n-1;i>=0;i--){
            scanf("%s",mapp[i]);
        }
        int ans = bfs();
        printf("%d\n",ans);
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/tjucxz/p/8874127.html