[2019HDU多校第五场][HDU 6626][C. geometric problem]
题目链接: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]的更多相关文章
- [2019HDU多校第四场][HDU 6617][D. Enveloping Convex]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6617 题目大意:给出一凸包\(P\),求最小的与\(P\)相似且对应边平行的多边形,使得题目给出的\( ...
- [2019HDU多校第三场][HDU 6603][A. Azshara's deep sea]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6603 题目大意:给出一个凸包,凸包内有若干个圆,要求画尽可能多的对角线使得他们两两不在凸包内相交且不与 ...
- 2019HDU多校第五场A fraction —— 辗转相除法|类欧几里得
题目 设 $ab^{-1} = x(mod \ p)$,给出 $x,p$,要求最小的 $b$,其中 $0< a < b, \ 1 < x<p,\ 3 \leq x\leq {1 ...
- hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】
题目链接 首先利用组合数学知识,枚举两人的总胜场数容易得到 这还不是卷积的形式,直接搞的话复杂度大概是O(n^2)的,肯定会TLE.但似乎和卷积有点像?想半天没想出来..多谢Q巨提醒,才知道可以用下面 ...
- hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力
题意: 定义一个排列的差分为后一项减前一项之差构成的数列,求对于n个数的排列,差分的字典序第k小的那个,n<=20,k<=1e4. 题解: 暴力打表找一遍规律,会发现,对于n个数的排列,如 ...
- 2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化)
题目链接 题意 : 给你两个n*n的矩阵,然后两个相乘得出结果是多少. 思路 :一开始因为知道会超时所以没敢用最普通的方法做,所以一直在想要怎么处理,没想到鹏哥告诉我们后台数据是随机跑的,所以极端数据 ...
- 2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)
题目链接 题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对. 思路 : 一开始想的很多,各种都想了,后 ...
- 2014 HDU多校弟五场J题 【矩阵乘积】
题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...
- 2014 HDU多校弟五场A题 【归并排序求逆序对】
这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...
随机推荐
- PCL学习(三) SAC-IA 估记object pose
SAC-IA是基于RANSAC算法的对齐算法 通过降采样提高法向计算.FPFH特征的计算 最后通过SAC-IA计算得到对齐的旋转和平移 #include <Eigen/Core> #inc ...
- PAT甲级 树 相关题_C++题解
树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...
- 【win10】 ffmpeg的安装
安装肯定要先下载,官方下载地址:http://www.ffmpeg.org/download.html 然后会进入这个页面. 然后根据你的操作系统选择 根据自己系统选择,我的系统是64位的所以下载的是 ...
- C# DateTime Subtract
DateTime start = DateTime.Now.AddDays(-20); DateTime end = DateTime.Now; TimeSpan ts = end.Subtract( ...
- Linux中 ls -l 命令显示结果中的每一列的含义
图片转载自:https://blog.csdn.net/zhuoya_/article/details/77418413 简单解释下: 1.第一列颜色框:文件类型列,这里简单描述几种常见类型,d表示目 ...
- VBA变量(七)
变量是一个指定的内存位置,用于保存脚本执行过程中可以更改的值.以下是命名变量的基本规则. 变量名称必须使用一个字母作为第一个字符. 变量名称不能使用空格,句点(.),感叹号(!)或字符@,&, ...
- bat实现守护程序保证平台正常运行
1.systeminfo查看系统最近一次重启时间: 2.杀进程: :start taskkill /f /im "xx.exe" goto start "xx.exe&q ...
- 搭建nginx静态资源站
搭建静态资源站包括以下几部分: root指令与alias指令的区别 使用gzip压缩资源 如何访问指定目录下的全部资源文件 如何限制访问流量 如何自定义log日志 root指令与alias指令的区别 ...
- Unity NavMesh 格式 解析 分析 对比 Recast Navigation
工具软件 Excel Nodepad++ Sublime Unity 5.4 / 5.6 VS RecastDemo CodeBlocks 分析过程以Unity项目-Demo13为例 一. 创建测试模 ...
- CVE-2019-0213: Apache Archiva Stored XSS
CVE-2019-0213: Apache Archiva Stored XSS Severity: Low Vendor:The Apache Software Foundation Version ...