圆周线

对于x-y​坐标平面上​n个点的集合,判断他们是不是都落在同一条圆周线上。

如果有一条圆周线,其圆心到每一个点的距离​d和半径​r的相对误差 \frac{\left | d-r \right |}{max\left ( 1,\left | r \right | \right )} 或绝对误差 \left | d-r \right |在10^-6​以内,我们就认为这些点都落在这个圆周线上。

输入描述

输入数据第一行,为一个整数​n [1,1000000]。

接下来​n行,每行包括两个浮点数,分别表示每个点的​x坐标和​y坐标[-1000,1000]。

输出描述

如果这​个n点在同一条圆周线上,输出三个数,表示这个圆的圆心坐标(x,y)​和半径r​,否则输出三个-1​。

如果有多个圆符合要求,输出任意一个即可,当你的答案的相对或绝对误差在10^-6​以内,你将通过此题。

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 4↵
  2. 0 2↵
  3. 0 -2↵
  4. 2 0↵
  5. -2 0↵
以文本方式显示
  1. 0 0 2↵
1秒 153600KB 0
#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
 
double min(double d,double r) 
{ 
   if(d<=r) return d; 
  else return r;  
} 
int main() 
{ 
 int n,i,flag=0; 
    double x,y,r; 
  scanf("%d",&n); 
    double point[n][2]; 
    for(i=0;i<n;i++) 
    { 
      scanf("%lf%lf",&point[i][0],&point[i][1]); 
 } 
  while(1) 
   { 
      if(n==1) 
       { 
          x=1000;y=1000;  //取(1000,1000)为圆心  
         r=sqrt(pow(fabs(point[0][0]-x),2)+pow(fabs(point[0][1]-y),2)); 
         flag=1;break; 
      } 
      if(n==2) 
       { 
          x=(point[0][0]+point[1][0])/2; 
         y=(point[0][1]+point[1][1])/2; 
         r=sqrt(pow(fabs(point[0][0]-x),2)+pow(fabs(point[0][1]-y),2));  //取中点为圆心 
           flag=1;break;  
     } 
      if(n>=3) 
        { 
          double x1,y1,k1,a1,a2,a3,x2,y2,k2,a4,a5,a6,d; 
          x1=(point[0][0]+point[1][0])/2; 
            y1=(point[0][1]+point[1][1])/2;  
          
         if((point[0][0]-point[1][0])==0) //水平  
         { 
            k1=0; 
              a1=0;a2=1;a3=y1-k1*x1;  
          } 
          if((point[0][1]-point[1][1])==0) //垂直  
         { 
              a1=1;a2=0;a3=x1; 
            }  
             if(((point[0][0]-point[1][0])!=0)&&((point[0][1]-point[1][1])!=0)) 
             { 
             k1=-1/((point[0][1]-point[1][1])/(point[0][0]-point[1][0])); //y-k1x=y1-k1x1 
               a1=-k1;a2=1;a3=y1-k1*x1;      //a1x+a2y=a3 
          } 
         
            x2=(point[1][0]+point[2][0])/2; 
            y2=(point[1][1]+point[2][1])/2; 
            if((point[1][0]-point[2][0])==0) //水平  
         { 
            k2=0; 
              a4=0;a5=1;a6=y2-k2*x2;  
          } 
          if((point[1][1]-point[2][1])==0) //垂直  
         { 
              a4=1;a5=0;a6=x2; 
            }  
             if(((point[1][0]-point[2][0])!=0)&&((point[1][1]-point[2][1])!=0)) 
             { 
             k2=-1/((point[1][1]-point[2][1])/(point[1][0]-point[2][0])); //y-k2x=y2-k2x2 
               a4=-k2;a5=1;a6=y2-k2*x2;      //a4x+a5y=a6 
          } 
          
            
           if(a5==0&&a2==0) break;  //三点共线  
           if(((a1*a5-a2*a4)==0)|| ((a1*a5-a2*a4)==0)) break; 
          
           x=(a3*a5-a2*a6)/(a1*a5-a2*a4); 
         y=(a3*a4-a1*a6)/(a2*a4-a1*a5); 
         r=sqrt(pow(fabs(point[0][0]-x),2)+pow(fabs(point[0][1]-y),2)); 
         for(i=0;i<n;i++) 
            { 
              d=sqrt(pow((point[i][0]-x),2)+pow((point[i][1]-y),2)); 
             if((fabs(d-r)/min(d,r))>0.000001) break; 
            } 
          if(i==n) 
           { 
              flag=1; 
                break;  
            }  
         else break;       
      } 
  } 
  if(flag) printf("%lf %lf %lf\n",x,y,r);  
   else printf("-1 -1 -1\n");   
 }  
发布了19 篇原创文章 · 获赞 1 · 访问量 172

猜你喜欢

转载自blog.csdn.net/CN_BIT/article/details/104649030