题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6626

题目大意:给出平面上六个点\(A,B,M,N,X,Y\)以及两条直线\(L1,L2\),要求在四边形\(ABNM\)内,直线\(L1\)上选一点\(S\),在四边形\(XYNM\)内,直线\(L2\)上选一点\(T\),使得\(S_{ASB}=S_{SMTN}=S_{XYT}\)

题解:设\(L1\)交\(ABNM\)于点\(P,Q\),不妨设\(S=P+t\cdot (Q-P), 0\leq t \leq 1\),则有$$2S_{ASB}=\vec{AB}\times \vec{AS}=\vec{AB}\times (\vec{AP}+t\cdot \vec{PQ})=\vec{AB}\times \vec{AP}+t\cdot \vec{AB}\times \vec{PQ}$$

   这个式子可以转换成为\(A+t\cdot B\)的形式。同理,三角形\(SMN,MNT,XYT\)均可以表示成这种形式,且\(ASB,SMN\)对应的\(t\)是\(S\)的坐标,不妨设为\(x\),另外两个三角形对应的\(t\)则设为\(y\)。这样我们就能得到$$\left\{\begin{matrix}
2S_{ASB}=\vec{AB}\times \vec{AP}+x\cdot \vec{AB}\times \vec{PQ}\\
2S_{SMN}=\vec{MN}\times \vec{MP}+x\cdot \vec{MN}\times \vec{PQ}\\
2S_{MNT}=\vec{MN}\times \vec{MP'}+y\cdot \vec{MN}\times \vec{P'Q'}\\
2S_{XYT}=\vec{XY}\times \vec{XP'}+y\cdot \vec{XY}\times \vec{P'Q'}
\end{matrix}\right.$$

   根据题目要求,我们就能得出$$\left\{\begin{matrix}
2S_{ASB}-2S_{XYT}=\vec{AB}\times \vec{AP}-\vec{XY}\times \vec{XP'}+x\cdot \vec{AB}\times \vec{PQ}-y\cdot \vec{XY}\times \vec{P'Q'}=0\\
2S_{ASB}-2S_{SMN}-2S_{MNT}=\vec{AB}\times \vec{AP}-\vec{MN}\times \vec{MP}-\vec{MN}\times \vec{MP'}+x\cdot(\vec{AB}\times \vec{PQ}-\vec{MN}\times \vec{PQ})-y\cdot \vec{MN}\times \vec{P'Q'}=0
\end{matrix}\right.$$

   这是一个二元一次方程组,当然我们也可以将其当成两条直线的标准式来看,求出他们的交点就能得出对应的答案了。

   这里要注意,这里求出来的表达式可能不会有对应的直线(比如\(0\cdot x+0\cdot y=c \neq 0\)),或者会出现两直线没有交点,重合等情况,需要进行特判。另外还需要注意\(x,y\)解出来的值必须在\([0,1]\)这个范围内,否则也是无解。

   另外,由于这题要求在多解时输出字典序最小的解,所以在我们求交点的时候就可以让点\(P\)的字典序比\(Q\)小,这样只要尽量让\(x,y\)取到最小值就好了

   由于为了防止爆精度,看到坐标范围较小,想练习手写分数运算等种种原因,这题我除了输出外都是纯整数运算,不用担心爆精度了以后感觉改代码都方便了许多(指不需要调\(eps\)←_←)

#include<bits/stdc++.h>
using namespace std;
struct Frac
{
long long p,q;
void read(){q=,scanf("%lld",&p);}
void simp()
{int d=abs(__gcd(p,q));
p/=d,q/=d;
if(q<)p*=-,q*=-;
if(p==)q=abs(q);
}
Frac operator +(const Frac &t)const
{
Frac res={p*t.q+t.p*q,q*t.q};
res.simp();return res;
}
Frac operator -(const Frac &t)const
{
Frac res={p*t.q-t.p*q,q*t.q};
res.simp();return res;
}
Frac operator *(const Frac &t)const
{
Frac res={p*t.p,q*t.q};
res.simp();return res;
}
Frac operator /(const Frac &t)const
{
Frac res={p*t.q,q*t.p};
res.simp();return res;
}
bool operator <(const Frac &t)const
{
return p*t.q<q*t.p;
}
bool operator ==(const Frac &t)const
{
return p==t.p && q==t.q;
}
void print(){printf("%.12f",1.0*p/q);}
};
int sgn(Frac k)
{
if(k.p>)return ;
if(k.p<)return -;
return ;
}
struct Point
{
Frac x,y;
void read(){x.read(),y.read();}
Point operator +(const Point &t)const{return {x+t.x,y+t.y};}
Point operator -(const Point &t)const{return {x-t.x,y-t.y};}
Frac operator *(const Point &t)const{return x*t.y-y*t.x;}
Point operator *(const Frac &t)const{return {x*t,y*t};}
Point operator /(const Frac &t)const{return {x/t,y/t};}
bool operator <(const Point &t)const{return x==t.x?y<t.y:x<t.x;}
bool operator ==(const Point &t)const{return x==t.x && y==t.y;}
void print(){x.print(),putchar(' '),y.print();}
bool check()
{
if(sgn(x)< || sgn(y)<)return false;
if((Frac){,}<x || (Frac){,}<y)return false;
return true;
}
}A,B,M,N,X,Y,f[],g[],ans[];
struct Line
{
Point p1,p2;
void read(){p1.read(),p2.read();}
bool check_isct(const Point &A,const Point &B)const
{return sgn((p2-p1)*(A-p1))*sgn((p2-p1)*(B-p1))<=;}
Point isct_Point(const Line &t)const
{
Frac a=(p2-p1)*(t.p1-p1);
Frac b=(p2-p1)*(p1-t.p2);
return (t.p1*b+t.p2*a)/(a+b);
}
}L1,L2;
struct Line_Standard
{
Frac A,B,C;
bool check(){return sgn(A) || sgn(B) || !sgn(C);}
bool check_isct(const Line_Standard &t)const
{
Frac tmp=A*t.B-B*t.A;
if(sgn(tmp))return true;
return sgn(C*t.B-B*t.C)==;
}
Point isct_Point(const Line_Standard &t)const
{
Frac tmp=A*t.B-B*t.A;
if(!sgn(tmp))
{
if(sgn(C)==)return {{,},{,}};
if(sgn(B)==)return {{,},{,}};
if(sgn(A)==)return {{,},{,}};
}
return {(B*t.C-C*t.B)/tmp,(C*t.A-A*t.C)/tmp};
}
void print()
{
A.print(),putchar(' ');
B.print(),putchar(' ');
C.print(),putchar('\n');
}
}h1,h2;
int T,cnt;
void rua(const Line &L,const Point &A,const Point &B,const int &lim)
{
if(L.check_isct(A,B) && sgn((L.p2-L.p1)*(A-B)) && cnt<lim)
if(!(L.isct_Point({A,B})==f[cnt]) || cnt==lim-)
f[++cnt]=L.isct_Point({A,B});
}
void cal(const Point &A,const Point &B,const Point &C,const Point &D)
{
Frac st=(B-A)*(C-A);
Frac delta=(B-A)*(D-C);
Frac ed=(B-A)*(D-A);
if(sgn(st)< || sgn(ed)<)
st.p=-st.p,delta.p=-delta.p;
g[++cnt]={st,delta};
}
void print(const Point &P)
{
Point S=f[]+(f[]-f[])*P.x;
Point T=f[]+(f[]-f[])*P.y;
S.print(),putchar(' ');
T.print(),putchar('\n');
}
void init()
{
cnt=;
A.read(),B.read();
M.read(),N.read();
X.read(),Y.read();
L1.read(),L2.read();
rua(L1,A,B,),rua(L1,B,N,);
rua(L1,N,M,),rua(L1,M,A,);
rua(L2,X,Y,),rua(L2,Y,N,);
rua(L2,N,M,),rua(L2,M,X,);
if(f[]<f[])swap(f[],f[]);
if(f[]<f[])swap(f[],f[]);
cnt=;
cal(A,B,f[],f[]);
cal(M,N,f[],f[]);
cal(M,N,f[],f[]);
cal(X,Y,f[],f[]);
h1={g[].y,(Frac){,}-g[].y,g[].x-g[].x};
h2={g[].y-g[].y,(Frac){,}-g[].y,g[].x-g[].x-g[].x};
if(!h1.check() || !h2.check())
{printf("-1\n");return;}
cnt=;
Frac tmp=h1.A*h2.B-h1.B*h2.A;
if(sgn(tmp)==)
{
if(sgn(h1.C*h2.B-h1.B*h2.C))
{printf("-1\n");return;}
if(!sgn(h1.A) && !sgn(h1.B))
swap(h1,h2);
if(h1.check_isct({{,},{,},{,}}))
ans[++cnt]=h1.isct_Point({{,},{,},{,}});
if(h1.check_isct({{,},{,},{,}}))
ans[++cnt]=h1.isct_Point({{,},{,},{,}});
if(h1.check_isct({{,},{,},{-,}}))
ans[++cnt]=h1.isct_Point({{,},{,},{-,}});
if(h1.check_isct({{,},{,},{-,}}))
ans[++cnt]=h1.isct_Point({{,},{,},{-,}});
for(int i=;i<=cnt;i++)
if(ans[i].check())
{print(ans[i]);return;}
printf("-1\n");
return;
}
ans[++cnt]=h1.isct_Point(h2);
if(ans[].check())
{print(ans[]);return;}
printf("-1\n");
}
int main()
{
scanf("%d",&T);
while(T--)init();
}

[2019HDU多校第五场][HDU 6626][C. geometric problem]的更多相关文章

  1. [2019HDU多校第四场][HDU 6617][D. Enveloping Convex]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6617 题目大意:给出一凸包\(P\),求最小的与\(P\)相似且对应边平行的多边形,使得题目给出的\( ...

  2. [2019HDU多校第三场][HDU 6603][A. Azshara's deep sea]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6603 题目大意:给出一个凸包,凸包内有若干个圆,要求画尽可能多的对角线使得他们两两不在凸包内相交且不与 ...

  3. 2019HDU多校第五场A fraction —— 辗转相除法|类欧几里得

    题目 设 $ab^{-1} = x(mod \ p)$,给出 $x,p$,要求最小的 $b$,其中 $0< a < b, \ 1 < x<p,\ 3 \leq x\leq {1 ...

  4. hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】

    题目链接 首先利用组合数学知识,枚举两人的总胜场数容易得到 这还不是卷积的形式,直接搞的话复杂度大概是O(n^2)的,肯定会TLE.但似乎和卷积有点像?想半天没想出来..多谢Q巨提醒,才知道可以用下面 ...

  5. hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力

    题意: 定义一个排列的差分为后一项减前一项之差构成的数列,求对于n个数的排列,差分的字典序第k小的那个,n<=20,k<=1e4. 题解: 暴力打表找一遍规律,会发现,对于n个数的排列,如 ...

  6. 2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化)

    题目链接 题意 : 给你两个n*n的矩阵,然后两个相乘得出结果是多少. 思路 :一开始因为知道会超时所以没敢用最普通的方法做,所以一直在想要怎么处理,没想到鹏哥告诉我们后台数据是随机跑的,所以极端数据 ...

  7. 2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)

    题目链接 题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对. 思路 : 一开始想的很多,各种都想了,后 ...

  8. 2014 HDU多校弟五场J题 【矩阵乘积】

    题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...

  9. 2014 HDU多校弟五场A题 【归并排序求逆序对】

    这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...

随机推荐

  1. 编写python高质量python代码的59个有效方法

    第1条:确认自己的python版本 第2条:遵循PEP8的风格 1.空格 对于 占据多行的长表达式来说, 除了首行之外的其余各行都应该在通常的缩进级别上再加4个空格. 每行字符数不应该超过79. 2. ...

  2. asp.net MVC 异步分页 PagedList

    最近做一个项目要有的异步分页,先记录下来! 引用: PagedList.css MvcPager.js <link href="~/css/sweetalert2.min.css&qu ...

  3. Comet OJ Contest #3

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  4. css 动画(一)transform 变形

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 有段时间我是没理清 transform.translate.transition 和 animation之 ...

  5. (五)CXF之添加拦截器

    一.需求分析 webService中的拦截器类似于servlet的Filter过滤器.一般用于调用服务前后先调用拦截器的方法. 二.案例 本章案例是基于上一章节的基础上添加拦截器的 2.1 服务端添加 ...

  6. (四)spring+servlet 整合

    一.Spring与Servlet的整合 1.1: 加入Spring的jar包.(要加web.jar包) 1.2: java工程中获取Spring的上下文对象. ApplicationContext c ...

  7. 【转载】使用appium遇到的坑

    问题 1. error: Failed to start an Appium session, err was: Error: Requested a new session but one was ...

  8. Trie树(字典树)-题解 P2580 【于是他错误的点名开始了】

    此题可以用STL中的map做,但是了解一下Trie树这个数据结构也是必须的. Trie树(又称字典树)有以下特点: 根节点不包含字符,除它之外的每一个节点都包含一个字符. 从根节点到某一节点,路径上经 ...

  9. HTTP参数污染(参数处理图)

  10. 安装mysql采坑记录

    安装之前彻底卸载之前的mysql,再次安装,初始化数据库那一步失败. 再次彻底卸载mysql,把原先的安装路径的文件夹删除,文件夹路径:C:\ProgramData,再次安装,成功. 总结:重装mys ...