• 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 }

    最后非常抱歉出题时没有考虑到同心圆的特殊情况,导致测试数据不够完善,特此致歉。

  • 相关阅读:
    WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)
    我的WCF之旅(13):创建基于MSMQ的Responsive Service
    .net程序集强名称签名实践
    WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Policy Injection Application Block 的集成
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等) 2
    WCF后续之旅(6): 通过WCF Extension实现Context信息的传递
    SilverlightCatchWcfError
    WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成
    WCF后续之旅(4):WCF Extension Point 概览
  • 原文地址:https://www.cnblogs.com/Never-Land/p/11914984.html
Copyright © 2020-2023  润新知