2019年广东外语外贸大学程序设计竞赛(新手赛)-F题(好快的刀)题解
Posted never-land
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019年广东外语外贸大学程序设计竞赛(新手赛)-F题(好快的刀)题解相关的知识,希望对你有一定的参考价值。
题面:
题目意为,任意连接两个圆的圆心形成一条直线,计算与该直线相交或相切的圆的数量,求这些直线最多能相交或相切多少个圆
解题思路:
遍历所有的圆,计算出两圆圆心生成的直线,再遍历其他的圆,检测这些圆的半径与圆心到直线的距离,即可确认直线与圆的关系。
坑点:
用函数思路解决时,需考虑斜率不存在问题(用向量解决即可规避该问题)
所有圆均为同心圆时,需特判(比赛测试数据并未考虑该特殊情况,赛后由广州大学的一位大佬发现,特此感谢)
标程:
出题时分别用函数的方法和向量的方法手搓了两份代码,最后用的标程是用kuangbin模板写的
向量的方法精度比函数的方法精度要高,但为降低难度还是放宽了精度的范围(大师兄说年轻人不能太毒瘤)
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 const double eps=1e-8; 5 const double inf =1e20; 6 //const double pi=acos(-1.0); 7 int sgn(double x){ 8 if(fabs(x)<eps) return 0; 9 if(x<0) return -1; 10 else return 1; 11 } 12 struct Point{ 13 double x,y; 14 Point(){} 15 Point(double _x,double _y){ 16 x=_x; 17 y=_y; 18 } 19 void input(){ 20 scanf("%lf%lf",&x,&y); 21 } 22 bool operator ==(Point b)const{ 23 return sgn(x-b.x)==0&&sgn(y-b.y)==0; 24 } 25 Point operator -(const Point &b)const{ 26 return Point(x-b.x,y-b.y); 27 } 28 double operator ^(const Point &b)const{ 29 return x*b.y-y*b.x; 30 } 31 double distance(Point p){ 32 return hypot(x-p.x,y-p.y); 33 } 34 }; 35 struct Line{ 36 Point s,e; 37 void input(){ 38 s.input(); 39 e.input(); 40 } 41 double length(){ 42 return s.distance(e); 43 } 44 double dispointtoline(Point p){ 45 return fabs((p-s)^(e-s))/length(); 46 } 47 }; 48 struct circle{ 49 Point p; 50 double r; 51 void input(){ 52 p.input(); 53 scanf("%lf",&r); 54 } 55 bool operator ==(circle v){ 56 return (p==v.p); 57 } 58 int relationline(Line v){ 59 double dst=v.dispointtoline(p); 60 if(sgn(dst-r)<0) return 2; 61 else if(sgn(dst-r)==0) return 1; 62 else return 0; 63 } 64 65 }; 66 int main(){ 67 int n,ans(2),cou,flag(0); 68 circle cir[105]; 69 Line line1; 70 cin>>n; 71 for(int i=0;i<n;i++) cir[i].input(); 72 for(int i=0;i<n;i++){ 73 if(cir[i]==cir[0]&&i==n-1)flag=1; 74 } 75 if(flag){ 76 cout<<n<<‘ ‘; 77 return 0; 78 } 79 for(int i=0;i<n;i++){ 80 for(int j=0;j<n;j++){ 81 cou=2; 82 if(i==j) continue; 83 line1.e=cir[i].p; 84 line1.s=cir[j].p; 85 for(int k=0;k<n;k++){ 86 if(k==i||k==j) continue; 87 if(cir[k].relationline(line1)!=0) cou++; 88 } 89 ans=max(ans,cou); 90 } 91 } 92 cout<<ans<<‘ ‘; 93 return 0; 94 }
最后非常抱歉出题时没有考虑到同心圆的特殊情况,导致测试数据不够完善,特此致歉。
以上是关于2019年广东外语外贸大学程序设计竞赛(新手赛)-F题(好快的刀)题解的主要内容,如果未能解决你的问题,请参考以下文章
急!求教“2014年TI杯大学生电子设计竞赛四川省赛题-H自动增益控制放大器(高职高专)”设计资料!谢谢了
2017年浙江中医药大学大学生程序设计竞赛(重现赛)H - 剪纸