20201012day33 刷题记录

1 LGP1354 房间最短路

problem

求房间内最短路。

solution

建图跑最短路?

直接模拟一个平面直角坐标系,看行走的路径的斜率(dfrac{y_2-y_1}{x_2-x_1})与边的交点

然而计算几何也能过?

复习6:计算几何

code

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;
int read()
{
    int a = 0,x = 1;char ch = getchar();
    while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
    return a*x;
}
int n,cnt=1;
const int maxn=1e5+10,maxm=1e6+10;
#define INF 0x3f3f3f
int head[maxn],to[maxm],nxt[maxm],tot;
double edge[maxm],d[maxn];
bool vis[maxn];
#include <queue>
priority_queue<pair<double,int> > q;
struct node{
	int id;double x,y;//平面直角坐标系内的点
}p[maxn][10];
void add(int x,int y,double z){
	to[++tot]=y;
	edge[tot]=z;
	nxt[tot]=head[x];
	head[x]=tot;
}
#define f(a,b,c,d) sqrt((a-c)*(a-c)+(b-d)*(b-d))
void init(){
	for(int i=1;i<=4;i++)
		p[0][i].x=0,p[0][i].y=5,p[n+1][i].x=10,p[n+1][i].y=5;
	for(int i=1;i<=n;i++){
		cin>>p[i][0].x;
		for(int j=1;j<=4;j++)
			cin>>p[i][j].y,p[i][j].x=p[i][0].x;
	}
	for(int i=1;i<=4;i++)
		p[0][i].id=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=4;j++)
			p[i][j].id=++cnt;
	for(int i=1;i<=4;i++)
		p[n+1][i].id=cnt+1; 
}
bool whet(int i,int j,double sx,double sy,double ex,double ey){
	if(j-i<2) return 1;
	for(int k=i+1;k<j;k++){
		double x=p[k][1].x;
		double y=((x-sx)*ey-(x-ex)*sy)/(ex-sx);
		if(!(y>=p[k][1].y&&y<=p[k][2].y)&&!(y>=p[k][3].y&&y<=p[k][4].y)) return 0;
	}
	return 1;
}
bool cckx(int i,int j,double sx,double sy,double ex,double ey){
	if(j-i<2)return 1;
	for(int k=i+1;k<j;k++){
		double x=p[k][1].x;
		double y=((x-sx)*ey-(x-ex)*sy)/(ex-sx);
		if(!(y>=p[k][1].y&&y<=p[k][2].y)&&!(y>=p[k][3].y&&y<=p[k][4].y))return 0;
	}
	return 1;
}
void dijkstra(){
	for(int i=1;i<=maxn;i++) d[i]=INF;
	memset(vis,0,sizeof(vis));
	d[1]=0;q.push(make_pair(0,1));
	while(q.size()){
		int x=q.top().second;q.pop();
		if(vis[x]) continue;vis[x]=1;
		for(int i=head[x];i;i=nxt[i]){
			int y=to[i];double z=edge[i];
			if(d[y]>d[x]+z) d[y]=d[x]+z,q.push(make_pair(-d[y],y));
		}
	}
}
int main(){
	n=read();
	init();
	if(cckx(0,n+1,0,5,10,5)) {printf("10.00");return 0;}
	for(int i=0;i<=n;i++) 
		for(int j=i+1;j<=n+1;j++)
			for(int l1=1;l1<=4;l1++)
				for(int l2=1;l2<=4;l2++)
					if(cckx(i,j,p[i][l1].x,p[i][l1].y,p[j][l2].x,p[j][l2].y))
						{add(p[i][l1].id,p[j][l2].id,f(p[i][l1].x,p[i][l1].y,p[j][l2].x,p[j][l2].y));}
	dijkstra();
	printf("%.2lf
",d[cnt+1]);
	return 0;
}
原文地址:https://www.cnblogs.com/liuziwen0224/p/20201012day33-001.html