Asia Jakarta Regional Contest 2019 I - Mission Possible
cf的地址
因为校强, "咕咕十段"队获得了EC-final的参赛资格
因为我弱, "咕咕十段"队现在银面很大
于是咕咕十段决定进行训练. 周末vp了一场, 这是赛后补题.
vp的时候想到了可以利用边界和切线, 但是没有仔细思考.
后来发现, 找到可以走的边界和切线之后, bfs一下就完事了啊.
题目给的eps限制使得我们可以合法的沿着切线和边界进行行走
关键在于找出"可以走的边界和切线"
如果一条切线在两个切点之间穿过了一个圆, 那么就不走这条切线(肯定可以走中间那个圆的某几条切线)
一条切线可以向两个切点外侧延伸, 直到与某个圆/边界相交.
主要麻烦的地方在于找圆的切线以及内外公切线. 以及我现在竟然能把直线求交写错...
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-7;
struct point{
double x, y;
point(double a = 0.0, double b = 0.0):x(a), y(b){}
point operator - (const point &A)const{
return point(x-A.x, y-A.y);
}
point operator + (const point &A)const{
return point(x+A.x, y+A.y);
}
void read(){
scanf("%lf%lf",&x,&y);
}
point rot(double theta)const{
return point(x*cos(theta)-y*sin(theta), x*sin(theta) + y*cos(theta));
}
double length()const{
return sqrt(x*x+y*y);
}
point norm()const {
return point(x/length(), y/length());
}
void output(){
printf("%lf %lf",x,y);
}
}pL, pR, S, T, C[52];
double r[52];
double cross(const point &A, const point &B){
return A.x * B.y -A.y * B.x;
}
struct Line{
point S, dlt;
double tmax, tmin;
Line(){
tmax = 1e20;
tmin = -1e20;
}
Line(point s, point t){
S = s;
dlt = t - s;
tmax = 1e20;
tmin = -1e20;
}
Line(point s, point t, double t1, double t2){
S = s; dlt = t - s;
tmin = t1; tmax = t2;
}
point operator () (const double &t)const{
return S + point(dlt.x*t, dlt.y*t);
}
bool through(const point &p)const {
return fabs(cross(p-S, dlt))<eps;
}
double gett(const point &p)const{
if(fabs(p.x - S.x) > eps){
return (p.x - S.x)/(dlt.x);
}else if(fabs(p.y - S.y)>eps){
return (p.y - S.y)/(dlt.y);
}else{
return 0;
}
}
bool contain(const point &p)const{
if(fabs(cross(p-S, dlt))>eps)return false;
double t = gett(p);
return t>=tmin-eps&&t<=tmax+eps;
}
point getp(double t)const{
return point(S.x+t*dlt.x, S.y+t*dlt.y);
}
void output(){
S.output();(S+dlt).output();
}
}L[6000];
Line tangent(point P, point C, double r, int flag){
double theta = acos(r/(P-C).length());
point v = (P-C).norm();
v = point(v.x*r, v.y*r);
v = v.rot(flag*theta);
point T = C + v;
return Line(P, T);
}
Line tangent_out(point C1, double r1, point C2, double r2, int flag){
if((fabs(r1-r2))<eps){
point v = (C1-C2).norm();
v = point(v.x * r1, v.y * r1);
v = v.rot(flag*acos(-1)/2);
return Line(C1+v, C2+v);
}else{
if(r1>r2){
swap(C1, C2);
swap(r1, r2);
}
//r1<r2
//r1/r2 = (l1)/(l2), l2-l1 = length(C1-C2)
double L = (C1 - C2).length();
L = L * r2/(r2-r1);
point v = (C1-C2).norm();
double theta = flag * acos(r2/L);
v = v.rot(theta);
return Line(C1 + point(v.x*r1, v.y*r1), C2 + point(v.x*r2, v.y*r2));
}
}
Line tangent_in(point C1, double r1, point C2, double r2, int flag){
point v = (C2 - C1);
point P = C1 + point(v.x*r1/(r1+r2), v.y*r1/(r1+r2));
double theta = flag*acos(r1/(P-C1).length());
v = v.norm().rot(theta);
return Line(C1 + point(v.x*r1, v.y*r1), C2 - point(v.x*r2,v.y*r2));
}
int cnt_lines = 0, cnt_lines2 = 0;
point intersect(const Line &L1, const Line &L2){
double C = cross(L1.dlt, L2.dlt);
if(fabs(C)<eps)return point(1e20, 1e20);
else{
double t = cross(L1.S - L2.S, L2.dlt)/cross(L2.dlt, L1.dlt);
return L1(t);
}
}
double mult(const point &P1, const point &P2){
return P1.x*P2.x + P1.y*P2.y;
}
bool between(point P, Line &L){
point S = L.S, T = L.S + L.dlt;
return mult(S-P, T-P) < -eps;
}
bool intersect(Line &L, point C, double r){
double dis = fabs(cross(C-L.S, L.dlt))/L.dlt.length();
if(dis > r - eps)return false;
double theta = acos(dis/r);
int flag = cross(C-L.S, L.dlt) > eps ? (1) : (-1);
point v = L.dlt.norm().rot(flag * acos(-1)/2 + theta);
point p = C + point(v.x*r, v.y*r);
if(between(p, L)){
return true;
}else{
double t = L.gett(p);
if(t < 0 && t > L.tmin){
L.tmin = t;
}
if(t > 0 && t < L.tmax){
L.tmax = t;
}
v = L.dlt.norm().rot(flag * acos(-1)/2 - theta);
p = C + point(v.x*r, v.y*r);
t = L.gett(p);
if(t < 0 && t > L.tmin){
L.tmin = t;
}
if(t > 0 && t < L.tmax){
L.tmax = t;
}
return false;
}
}
int N;
bool visited[6000];
int pre[6000], dis[6000];
int q[6000];
void output(int x, int cnt){
if(pre[x] == 0){
printf("%d\n",cnt);
}else{
output(pre[x], cnt+1);
point p = intersect(L[x], L[pre[x]]);
p.output();printf("\n");
}
}
void bfs(){
int head = 0, tail = 0;
visited[0] = true; dis[0] = 0;//S
for(int i = 1; i <= cnt_lines2; ++i){
if(L[i].contain(S)){
pre[i] = 0; dis[i] = 1;
visited[i] = true;
q[tail++] = i;
}
}
while(head!=tail){
int x = q[head++];
if(L[x].contain(T)){
output(x, 0);
break;
}else{
for(int i=1;i<=cnt_lines2;++i){
if(!visited[i]){
point p = intersect(L[i],L[x]);
if(L[i].contain(p)&&L[x].contain(p)){
q[tail++] = i;
visited[i] = true;
pre[i] = x;
dis[i] = dis[x] + 1;
}
}
}
}
}
}
int main(){
scanf("%d",&N);
pL.read();pR.read();
S.read();T.read();
for(int i = 1;i <= N;++i){
C[i].read();scanf("%lf", r+i);
}
L[++cnt_lines] = Line(S, T);
for(int i = 1;i <= N;++i){
L[++cnt_lines] = tangent(S, C[i], r[i], 1);
L[++cnt_lines] = tangent(S, C[i], r[i], -1);
L[++cnt_lines] = tangent(T, C[i], r[i], 1);
L[++cnt_lines] = tangent(T, C[i], r[i], -1);
}
for(int i = 1;i <= N;++i){
for(int j = i + 1;j <= N;++j){
L[++cnt_lines] = tangent_out(C[i], r[i], C[j], r[j], 1);
L[++cnt_lines] = tangent_out(C[i], r[i], C[j], r[j],-1);
L[++cnt_lines] = tangent_in(C[i], r[i], C[j], r[j], 1);
L[++cnt_lines] = tangent_in(C[i], r[i], C[j], r[j],-1);
}
}
for(int i=1;i<=cnt_lines;++i){
bool flag = true;
for(int j = 1;j <= N;++j){
if(intersect(L[i], C[j], r[j])){
flag = false;break;
}
}
if(flag){
L[++cnt_lines2] = L[i];
}
}
L[++cnt_lines2] = Line(point(pL.x, pL.y), point(pL.x, pR.y), 0, 1);
L[++cnt_lines2] = Line(point(pR.x, pL.y), point(pR.x, pR.y), 0, 1);
L[++cnt_lines2] = Line(point(pL.x, pL.y), point(pR.x, pL.y), 0, 1);
L[++cnt_lines2] = Line(point(pL.x, pR.y), point(pR.x, pR.y), 0, 1);
for(int i=1;i<=cnt_lines2 - 4;++i){
for(int j=cnt_lines2 - 3;j<=cnt_lines2;++j){
point p = intersect(L[i], L[j]);
double t = L[i].gett(p);
if(t<0&&t>L[i].tmin){
L[i].tmin = t;
}
if(t>0&&t<L[i].tmax){
L[i].tmax = t;
}
}
}
bfs();
return 0;
}
Asia Jakarta Regional Contest 2019 I - Mission Possible的更多相关文章
- 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest
目录 Contest Info Solutions A. Copying Homework C. Even Path E. Songwriter G. Performance Review H. Tw ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings
As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC ...
- 2018 ICPC Asia Jakarta Regional Contest
题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . Ø Ø Ø Ø . Ο Ο:当场 Ø:已补 . : 待补 A. Edit Distance Thin ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path
Pathfinding is a task of finding a route between two points. It often appears in many problems. For ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest A. Copying Homework
Danang and Darto are classmates. They are given homework to create a permutation of N integers from ...
- 模拟赛小结:2019-2020 ICPC, Asia Jakarta Regional Contest
比赛链接:传送门 离金最近的一次?,lh大佬carry场. Problem A. Copying Homework 00:17(+) Solved by Dancepted 签到,读题有点慢了.而且配 ...
- 2016 Asia Jakarta Regional Contest L - Tale of a Happy Man UVALive - 7722
UVALive - 7722 一定要自己做出来!
- 2016 Asia Jakarta Regional Contest A - Confusing Date Format UVALive 7711 【模拟题】
A - Confusing Date Format 题目大意:就是有六种日期格式,给你一个字符串,判断它能组成多少种可能的日期. 第一次WA是:1.没有判重,2.没有特判题目要求的数据,3.判断天数时 ...
随机推荐
- UML交互图
UML 交互图主要包括对象和消息两类元素,创建交互图的过程实际上就是向对象分配任务的过程,是可视化系统的交互行为. UML 交互图包括两种:序列图和协作图. 序列图:显示对象之间的关系,强调对象之间消 ...
- Delphi阿里云对象存储OSS【支持上传文件、下载文件、删除文件、创建目录、删除目录、Bucket操作等】
作者QQ:(648437169) 点击下载➨Delphi阿里云对象存储OSS 阿里云api文档 [Delphi阿里云对象存储OSS]支持 获取Bucket列表.设置Bucket ...
- drf源码系列
过滤器 对查询出来的数据进行筛选可写可不写 from rest_framework.filters import BaseFilterBackend 源码 ''' def filter_queryse ...
- excel数据分析流程
1.获取数据 2.去掉空值.空行.重复行 3.去掉无用行,筛选出需要行 4.分组数据 5.数据排序
- FMX 窗口置顶 或置底 xe10
FMX 窗口置顶 或置底 xe10 Popup 置底 StayOnTop 置顶
- jQuery格式化显示json数据
一.概述 JSONView 在gitlab上面,有一个jQuery JSONView插件,地址为:https://github.com/yesmeck/jquery-jsonview demo地址:h ...
- Java CookieUtils
Java CookieUtils /** * <html> * <body> * <P> Copyright 1994 JsonInternational</ ...
- 为什么UDP有时比TCP更有优势?
随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单.传输快的优势,在越来越多场景下取代了TCP.1.网速的提升给UDP稳定性提供可靠网络保障 CDN服务商Akamai(NASDAQ: A ...
- scrapy xpath去除空格
content = response.xpath("normalize-space('//img/@src')")
- 【RAC】 RAC For W2K8R2 安装--结尾篇(十)
[RAC] RAC For W2K8R2 安装--结尾篇(十) 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其 ...