hihoCoder - 1633(2017北京icpc现场赛-G题)

题意:给你一个三角形的三个坐标,还有一张图,让你从图中的左下角走到右上角,左下角坐标是(0,0),每两点之间的长度是1,'.'代表能走,'#'代表不能走,并且每条路径不能碰到三角形内部,让你求最短路径长度。                                                   

北京错失铜牌,打铁而归,总是感觉很遗憾,也有点难受,这个题当时场上差一丢丢能出的,后来时间没赶上。                    

 

 

代码:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define ri(n) scanf("%d",&n)
#define oi(n) printf("%d\n",n)
#define rl(n) scanf("%lld",&n)
#define ol(n) printf("%lld\n",n)
#define rep(i,l,r) for(i=l;i<=r;i++)
#define rep1(i,l,r) for(i=l;i<r;i++)
#define eps 1e-8
#define zero(x)(((x)>0?(x):-(x))<eps)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int epg=10-8;
int vis[1000][1000];
int dx[]={-1,0,1,-1,1,-1,0,1};
int dy[]={1,1,1,0,0,-1,-1,-1};
int n,m;
int maps[1000][1000];
char s[1000][1000];
struct node
{
    int x,y;
    int step;
    node(int a,int b,int c):x(a),y(b),step(c){}
};
struct Point
{
    double x;
    double y;
};
typedef struct Point point;
point p1,p2,p3;
double multi(point p0,point p1,point p2)//叉积
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool isIntersected(point s1,point e1,point s2,point e2)//两线段交,不包括端点相交
{
    return (max(s1.x,e1.x)>=min(s2.x,e2.x)) &&
           (max(s2.x,e2.x)>=min(s1.x,e1.x)) &&
           (max(s1.y,e1.y)>=min(s2.y,e2.y)) &&
           (max(s2.y,e2.y)>=min(s1.y,e1.y)) &&
           (multi(s1,s2,e1)*multi(s1,e1,e2)>0) &&
           (multi(s2,s1,e2)*multi(s2,e2,e1)>0);
}
double xmult(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int dot_online_in(point p,point l1,point l2)//判断点在线段上,包括端点
{
    return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}
double area(point p1,point p2,point p3)//求三角形面积
{
    return  abs((p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x))/2.0;
}
int pansan(point e)//判断点在三角形内部
{
    if(!dot_online_in(e,p1,p2)&&!dot_online_in(e,p2,p3)&&!dot_online_in(e,p3,p1)&&
       (area(e,p1,p2)+area(e,p2,p3)+area(p3,p1,e)<area(p1,p2,p3)+eps))
           return 1;
    else
        return 0;

}
int same(point p1,point p2)
{
    if(p1.x==p2.x&&p1.y==p2.y)
        return 1;
    else
        return 0;
}
int pan(point p1,point p2,point p3,point e1,point e2)
{
    if(isIntersected(p1,p2,e1,e2)||isIntersected(p2,p3,e1,e2)||isIntersected(p3,p1,e1,e2))
        return 0;
    else
    {
        //int flag1=0,flag2=0;
        if((same(e1,p1)&&!same(e2,p2)&&!same(e2,p3)&&dot_online_in(e2,p2,p3))||
           (same(e1,p2)&&!same(e2,p1)&&!same(e2,p3)&&dot_online_in(e2,p1,p3))||
            (same(e1,p3)&&!same(e2,p1)&&!same(e2,p2)&&dot_online_in(e2,p1,p2))||
            (same(e2,p1)&&!same(e1,p2)&&!same(e1,p3)&&dot_online_in(e1,p2,p3))||
           (same(e2,p2)&&!same(e1,p1)&&!same(e1,p3)&&dot_online_in(e1,p1,p3))||
            (same(e2,p3)&&!same(e1,p1)&&!same(e1,p2)&&dot_online_in(e1,p1,p2))
           )
            return 0;
        else
        {
            if(((dot_online_in(e1,p1,p2)||dot_online_in(e1,p2,p3)||dot_online_in(e1,p3,p1))&&pansan(e2))
               ||((dot_online_in(e2,p1,p2)||dot_online_in(e2,p2,p3)||dot_online_in(e2,p3,p1))&&pansan(e1))
               )
                return 0;
            else
            {
                if((!same(e1,p1)&&!same(e1,p2)&&dot_online_in(e1,p1,p2)&&( (!same(e2,p1)&&!same(e2,p3)&&dot_online_in(e2,p1,p3))||(!same(e2,p2)&&!same(e2,p3)&&dot_online_in(e2,p2,p3))))||
                   (!same(e1,p2)&&!same(e1,p3)&&dot_online_in(e1,p2,p3)&&( (!same(e2,p1)&&!same(e2,p3)&&dot_online_in(e2,p1,p3))||(!same(e2,p2)&&!same(e2,p1)&&dot_online_in(e2,p2,p1))))||
                   (!same(e1,p3)&&!same(e1,p1)&&dot_online_in(e1,p3,p1)&&( (!same(e2,p1)&&!same(e2,p2)&&dot_online_in(e2,p1,p2))||(!same(e2,p2)&&!same(e2,p3)&&dot_online_in(e2,p2,p3))))
                   )

                    return 0;
                else
                {
                     if(pansan(e1)||pansan(e2))
                        return 0;
                     else
                     {
                         if(  ((dot_online_in(p1,e1,e2)&&!same(e1,p1)&&dot_online_in(e2,p2,p3)&&!same(e2,p2)&&!same(e2,p3))||(dot_online_in(p1,e1,e2)&&!same(e2,p1)&&dot_online_in(e1,p2,p3)&&!same(e1,p2)&&!same(e1,p3)))
                              ||((dot_online_in(p2,e1,e2)&&!same(e1,p2)&&dot_online_in(e2,p1,p3)&&!same(e2,p1)&&!same(e2,p3))||(dot_online_in(p2,e1,e2)&&!same(e2,p2)&&dot_online_in(e1,p1,p3)&&!same(e1,p1)&&!same(e1,p3)))
                              ||((dot_online_in(p3,e1,e2)&&!same(e1,p3)&&dot_online_in(e2,p1,p2)&&!same(e2,p1)&&!same(e2,p2))||(dot_online_in(p3,e1,e2)&&!same(e2,p3)&&dot_online_in(e1,p1,p2)&&!same(e1,p1)&&!same(e1,p2)))
                            )
                                return 0;
                         else
                            return 1;
                     }
                        //return 1;
                }

            }
                //return 1;
        }
    }
}
int bfs(){
	memset(vis,false,sizeof(vis));
	queue<node> q;
	vis[0][0] = true;
	q.push(node(0,0,0));
	while(!q.empty()){
		node p = q.front();
		q.pop();
		int nx,ny;
		for(int i = 0 ; i < 8 ; i ++){
			nx = p.x + dx[i];
			ny = p.y + dy[i];
			if(nx < 0 || nx >= n || ny < 0 || ny >= n)continue;
			if(maps[nx][ny] == '#' || vis[nx][ny])continue;
			Point q1,q2;
			q1.x = p.x;
			q1.y = p.y;
			q2.x = nx;
			q2.y = ny;
			//cout << "p.x = " << p.x << " p.y = " << p.y << endl;
			if(pan(p1,p2,p3,q1,q2)){
				vis[nx][ny] = true;
				//cout << "nx = " << nx << " ny = " << ny << endl;
				q.push(node(nx,ny,p.step+1));
				if(nx == n-1 && ny == n-1){
					return p.step+1;
				}
			}
		}
	}
	return -1;
}
int main()
{
    while(scanf("%d",&n) != EOF){
    	cin>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;
    	//cin>>p1.y>>p1.x>>p2.y>>p2.x>>p3.y>>p3.x;
    	for(int i = 0 ; i < n ; i ++){
    		scanf("%s",s[i]);
    	}
    	for(int i = 0 ; i < n ; i ++){
    		for(int j = 0 ; j < n ; j ++){
    			maps[i][j] = s[n-1-j][i];
    			//maps[i][j] = s[i][j];
    		}
    	}
    	// for(int i = 0 ; i < n ; i ++){
    	// 	for(int j = 0 ; j < n ; j ++){
    	// 		cout << maps[i][j];
    	// 	}
    	// 	cout << endl;
    	// }
    	cout << bfs() << endl;
    }
    return 0;
}


                                                                                                                                                                               

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值