链接:https://ac.nowcoder.com/acm/contest/553/A
题目描述
Chino的数学很差,因此Cocoa非常担心。这一天,Cocoa准备教Chino学习圆与直线的位置关系。
众所周知,直线和圆有三种位置关系:相离、相切、相割,主要根据圆心到直线的距离来判定。
现在我们来看看作业吧:
是以整点为圆心、正整数为半径的圆,整点分别是圆外一点以及轴上的一点,形成一条圆的割线(也就是和圆有两个交点)。现在Cocoa想要知道,的值是多少?
题目对于Chino来说太难啦,你能帮一帮Chino吗?
输入描述:
六个正整数x0, y0, r, x1, y1, y2
输出描述:
题目要求的答案,精确到整数
示例1
输入
2 2 1 3 1 2
输出
1
思路:
一开始想的是求出直线与圆的交点的两个坐标,然后直接算出|BD|和|BE|的长度。
这样做需要求出直线和圆的方程然后联立解二元一次方程。
这里参考的另一个博主的给出的方法求得。
链接如下:
代码如下:
#include <bits/stdc++.h>
using namespace std;
double x00,y00,r,x11,y11,x22,y22;
double k,b;
double x33,y33,x44,y44;
double aa,bb,cc;
double re;
double ans;
//求y=kx+b中的k和b
void solkb()
{
b=y22;
k=(y11-y22)/x11;
}
//求圆和直线联立的ax+by+c=0中的a,b,c
void solabc()
{
aa=1+k*k;
bb=2*k*(b-y00)-2*x00;
cc=x00*x00+(b-y00)*(b-y00)-r*r;
}
//解二元一次方程
void solxy34()
{
re=bb*bb-4*aa*cc;
x33=(-bb+sqrt(re))/(2*aa);
x44=(-bb-sqrt(re))/(2*aa);
y33=k*x33+b;
y44=k*x44+b;
}
//根据坐标系求距离
void solve()
{
double a1=fabs(y33-y11);
double b1=fabs(x11-x33);
double r1=sqrt(a1*a1+b1*b1);
double a2=fabs(y44-y11);
double b2=fabs(x11-x44);
double r2=sqrt(a2*a2+b2*b2);
ans=r1*r2;
}
int main()
{
x22=0;
scanf("%lf%lf%lf%lf%lf%lf",&x00,&y00,&r,&x11,&y11,&y22);
solkb();
solabc();
solxy34();
solve();
printf("%.0lf\n",ans);
return 0;
}
通过看排名大佬提交的代码,发现还有一种更简便的方法:
直接用B到O的距离的平方减去半径的平方就是答案。。。感觉我高中的时候应该知道为什么。。
参考代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int x0,y0,r,x1,y1,y2;
while(EOF!=scanf("%d%d%d%d%d%d",&x0,&y0,&r,&x1,&y1,&y2)){
ll a=1ll*(x1-x0)*(x1-x0)+1ll*(y1-y0)*(y1-y0);
double ans=a-1ll*r*r;
printf("%.0lf\n",ans);
}
return 0;
}