题目:The Kth Circle

题意:平面上给定n个点的坐标,我们可以选其中3点构成一个圆,当然也就有3段弧,我们定义第K个圆满足条件:

(1)除了已选的3个点,剩下的n-3个点中有K个点在圆内,有n-K-1个点在圆外

(2)保证所有的点在圆的三条弧中其中一条弧的一侧

解析:本题实际上就是得到这样一个结论,满足条件的圆其中有两点一定在这些点的凸包上,并且这两点相邻,这样我们就可以先

求凸包,然后枚举凸包的每条边,设边的端点为A,B,再枚举点B,然后我们把角APB按照从小到大的顺序排序,其中第K+1个就

是我们要求的,对于枚举凸包的每一条边都求出第K+1个点与凸包边的端点形成的圆的半径,记录最小的。

由于点的数目2000,比较大,直接枚举会超时。所以采用堆优化。

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cmath>
using namespace std;
const int N=2005;
struct Point
{
int x,y;
};
struct HEAP
{
double var;
int id;
};
HEAP heap[N];//小顶堆
Point p[N];
int stack[N];
bool readIn(int &N,int &K)
{
if(scanf("%d%d",&N,&K)==EOF)
return false;
for(int i=1;i<=N;i++)
scanf("%d%d",&p[i].x,&p[i].y);
return true;
}
int cross(Point A,Point B,Point C)
{
return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
}
bool cmp(const Point &a,const Point &b)
{
return cross(p[1],a,b)>0 ;
}
double dist(Point A,Point B)
{
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double getAng(const Point &a,const Point &b,const Point &c)
{
double A,B,C;
C=dist(b,c);
A=dist(a,b);
B=dist(a,c);
double ang_a=acos((A*A+B*B-C*C)/(2*A*B));
return ang_a;
}
/**根据角a和b对点排序*/
bool heapCmp(const HEAP &a,const HEAP &b)
{
return a.var>b.var;
}
void insert(const HEAP &a,int &cnt)
{
heap[++cnt]=a;
int  j=cnt;
while(j>1)
{
if(heapCmp(heap[j/2],heap[j]))
{
swap(heap[j/2],heap[j]);
j/=2;
}
else break;
}
}
void heapDown(const int &id,const int &cnt)
{
int lc=id*2,rc=id*2+1,j=id;
if(lc<=cnt&&heapCmp(heap[j],heap[lc])) j=lc;
if(rc<=cnt&&heapCmp(heap[j],heap[rc])) j=rc;
if(j!=id)
{
swap(heap[id],heap[j]);
heapDown(j,cnt);
}
return;
}
/**已知三点求三角形的面积*/
double triangleArea(const Point &a,const Point &b,const Point &c)
{
return fabs(cross(a,b,c))/2.0;
}
/**已知圆上三点求圆半径*/
double getRadius(const Point &a,const Point &b,const Point &c)
{
double A=dist(a,b);
double B=dist(a,c);
double C=dist(b,c);
return (A*B*C)/(triangleArea(a,b,c)*4.0);
}
void Solve(const int &N,const int &K)
{
int id=1;
for(int j=1;j<=N;j++)
if(p[id].x<p[j].x||(p[id].x==p[j].x&&p[id].y<p[j].y))
id=j;
swap(p[1],p[id]);
sort(p+2,p+N+1,cmp);
int top=0;
stack[++top]=1,stack[++top]=2;
for(int i=3;i<=N;i++)
{
while(top>1&&cross(p[stack[top-1]],p[stack[top]],p[i])<0) top--;
stack[++top]=i;
}
stack[++top]=stack[1];
double ans=1000000000;
HEAP tmp;
for(int i=1;i<top;i++)
{
int cnt=0;
for(int j=1;j<=N;j++)
{
if(j!=stack[i]&&j!=stack[i+1])
{
tmp.id=j;
tmp.var=getAng(p[j],p[stack[i]],p[stack[i+1]]);
if(cnt<K) insert(tmp,cnt);
else
{
if(heapCmp(tmp,heap[1]))
{
heap[1]=tmp;
heapDown(1,cnt);
}
}
}
}
double tmp=getRadius(p[stack[i]],p[stack[i+1]],p[heap[1].id]);
ans=ans>tmp? tmp:ans;
}
printf("%.2lf\n",ans);
}
int main()
{
int N,K;
while(readIn(N,K))
{
K++;
Solve(N,K);
}
return 0;
}

NEFU709(第K个圆的半径)相关推荐

  1. python输入半径求圆的面积、保留三位小数_编写程序,输入圆的半径,求该圆的面积与周长(保留三位小数)。 /* 程序功能:输入圆的半径,计算圆的面积与周长*/_学小易找答案...

    [编程题]从字符串中删除指定的字符.同一字母的大小写按不同字符处理. 例如:若程序执行时,输入字符串为: turbo c and Borland c++ ,从键盘上输入字符: n ,则输出后变为: t ...

  2. KNN分类器、最近邻分类、KD树、KNN分类的最佳K值、基于半径的最近邻分类器、KNN多分类、KNN多标签分类、KNN多输出分类、KNN分类的优缺点

    KNN分类器.最近邻分类.KD树.KNN分类的最佳K值.基于半径的最近邻分类器.KNN多分类.KNN多标签分类.KNN多输出分类.KNN分类的优缺点 目录

  3. 用python的turtle画圆-(python海龟绘图怎么增加每次画圆的半径)

    Python 如何调用graphics库画圆弧,半圆等 import turtle turtle.left(135) turtle.circle(120,90) turtle.done() pytho ...

  4. java定义一个类计算圆的半径,C++编程:定义一个圆类要求属性为半径,操作为计算圆的周长和面积...,java编程:定义一个圆类,属性为半径,方法为对输入的半径计...

    导航:网站首页 > C++编程:定义一个圆类要求属性为半径,操作为计算圆的周长和面积...,java编程:定义一个圆类,属性为半径,方法为对输入的半径计 C++编程:定义一个圆类要求属性为半径, ...

  5. 创建一个圆类Circle的对象,分别设置圆的半径计算并分别显示圆半径、圆面积、圆周长。...

    编写一个圆类Circle,该类拥有: ①一个成员变量 Radius(私有,浮点型): // 存放圆的半径: ②两个构造方法 Circle( ) // 将半径设为0 Circle(double r ) ...

  6. 给定圆的半径r,求圆的面积。

    //编写人:yike //时间:2021/1/25/12:28 //问题描述 //给定圆的半径r,求圆的面积. //输入格式 //输入包含一个整数r,表示圆的半径. //输出格式 //输出一行,包含一 ...

  7. HALCON示例程序measure_circles.hdev测量圆的半径

    HALCON示例程序measure_circles.hdev测量圆的半径 示例程序源码(加注释) 关于显示类函数解释 dev_update_off () read_image (Image, 'cir ...

  8. python输入圆的半径公式_[图文]铁路曲线正矢的计算公式

    一.圆曲线正矢的计算 1.1 圆曲线正矢的计算公式 取圆曲线上两点拉一直线,叫做弦.弦上任意点至曲线上的垂直距离叫矢或叫矢距.在弦中央点的矢距叫正矢(下图). AB一弦;AC.CB一半弦;CD一正矢; ...

  9. 【Java】编写Java应用程序,完成从键盘输入圆的半径,求圆的周长和面积并输出结果的功能...

    计算公式 周长=2*PI*R 面积=PI*R*R 控制台 import java.io.*; public class MyTest {/*输入圆的半径,求圆的周长和面积*/public static ...

最新文章

  1. C语言程序设计50例(一)(经典收藏)
  2. vc6.0 点击鼠标获取mysql数据库所在行_VC6.0连接到mysql数据库
  3. 安装phpredis扩展以及phpRedisAdmin工具
  4. 使用Hot Chocolate创建ASP.NET Core GraphQL服务
  5. 关于freemarker的classic_compatible属性的使用场景和解决
  6. 公司冷备服务器1.100切换到1.99
  7. python 随机选择字符串中的一个字符
  8. 哲学家就餐问题---c语言
  9. 带你开发一款给Apk中自动注入代码工具icodetools(完善篇)
  10. 【C++ 程序】 TVJ Complex Calculator (v 2.1) 复数计算器
  11. 一个小白的自渡-Git 仓库基础操作
  12. DETR3D模型源码导读 MMDetection3D构建流程
  13. Java提取身份证照片数据,so easy
  14. numpy的文件存储.npy .npz 文件详解
  15. ubuntu安装显卡驱动的三种方法
  16. C++ std::set<>是什么 怎么用 遍历
  17. 三大范式,ER图,外键,视图,索引,触发器
  18. Codeforces Round #376 (Div. 2) D. 80-th Level Archeology —— 差分法 + 线段扫描法
  19. dashboard的yaml配置文件
  20. RecyclerView(一)最简单的recyclerview

热门文章

  1. springboot 切换日志实现
  2. 哪些情况不适合建索引
  3. 获取商品列表(Feign)
  4. php将数组中元素打乱顺序,PHP公开课|学会随机打乱数组元素顺序的函数,你的PHP会学的更好...
  5. webflux系列--基础
  6. Shell循环与结构化命令
  7. python两个数相加时_怎么用python让两个小数相加
  8. JAVA数据类型的转换及数据的原反补三码
  9. stm32定时器中断类型分析
  10. 全国首家工资总额负面清单管理试点企业获批