二维坐标平面上有一圆 P , 圆 P 的半径为 r , 且圆心位于坐标原点 . 两条相交线段AB , CD将圆切割为 4 个部分 , 求其中最大部分的面积 .
Input
一行包含 9 个整数 r, xA, yA, xB, yB, xC, yC, xD, yD(1 ≤ r ≤ 5000, - 5000 ≤ xA, yA, xB, yB, xC, yC, xD, yD ≤ 5000) , 分别表示圆 P 的半径和点 A, B, C, D 的横纵坐标 .
输入保证两条线段 AB 和 CD 的端点都在圆外 , 且其交点严格位于圆 P 的内部 .
Output
输出一行一个浮点数 , 表示答案 . 设输出的答案为 a , 标准答案为 b , 你的答案被认为是正确的 , 当且仅当相对误差小于或等于 10 - 6 , 即 .
Example
Input
1 2 2 -3 -3 -4 4 5 -5
Output
0.7853981634
思路:数学题编成代码
最后错:
//double te=2s/(rr);//不能用正弦!高中就知道一个值有两个解了
//double thra=fabs(asin(te<=1?te:te-2));//这句话没用,不要侥幸,就是错在这,好好想想
苍天有眼C题终于A了,数学麻瓜无疑,正弦定理会有多解
我明明发现不对劲
真是写昏了都不觉得改找错
中间错:
要考虑优弧,
要考虑斜率不存在
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<vector>
#include<map>
#include<set>
#include<ctype.h>
#include<stack>
#include<queue>
#ifdef LOCAL
FILE*FP=freopen("text.in","r",stdin);
//FILE*fp=freopen("text.out","w",stdout);
#endif
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define _forplus(i,a,b) for( register int i=(a); i<=(b); i++)
#define _forsub(i,a,b) for( register int i=(a); i>=(b); i--)
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define INF 0x3f3f3f3f
#define N 100005
const double pi=acos(-1);
struct Poi
{
double x,y;
Poi(double x=0,double y=0):x(x),y(y){}
friend istream&operator>>(istream&input,Poi&p){
input>>p.x>>p.y;
return input;
}
};
inline double han(double a11,double a12,double a21,double a22){
return a11*a22-a12*a21;
}
void get(Poi&m,double a11,double a12,double a21,double a22,double b1,double b2){
double d=han(a11,a12,a21,a22);
double d1=han(b1,a12,b2,a22);
double d2=han(a11,b1,a21,b2);
m.x=d1/d;
m.y=d2/d;
}
inline double chu(double a,double b,double c,double d){
return (a-b)/(c-d);
}
void solve(Poi&A,Poi&B,double a,double b,double c,double k,double b1){
double deta=b*b-4*a*c;
A.x=(-b+sqrt(deta))/(2*a);
B.x=(-b-sqrt(deta))/(2*a);
A.y=k*A.x+b1;
B.y=k*B.x+b1;
}
double sq(Poi&a,Poi&b,Poi&c){
double te=fabs(han(c.x-a.x,c.y-a.y,c.x-b.x,c.y-b.y));
return fabs(han(c.x-a.x,c.y-a.y,c.x-b.x,c.y-b.y))/2;//三角形面积/2
}//三角形面积
inline double d(Poi a,Poi b ){
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
double costhra(Poi o,Poi a,Poi b){
return (pow(d(o,a),2)+pow(d(o,b),2)-pow(d(a,b),2))/(2*d(o,a)*d(o,b));
}
double by(Poi&a,Poi&b,double r,bool l){
Poi o(0,0);
double s=sq(o,a,b);
double thra=acos(costhra(o,a,b));
//double te=2*s/(r*r);//不能用正弦!高中就知道一个值有两个解了
//double thra=fabs(asin(te<=1?te:te-2));//这句话没用,不要侥幸,就是错在这,好好想想
return (l?thra:2*pi-thra)*r*r/2-(l?s:-s);
}//弧面积
bool bl(Poi a,Poi b,Poi o,Poi m){
double j1=han(a.x-o.x,a.y-o.y,b.x-o.x,b.y-o.y);
double j2=han(a.x-m.x,a.y-m.y,b.x-m.x,b.y-m.y);
if((j1>0&&j2>0)||(j1<0&&j2<0))return true;
return false;
}//同侧同好true,
int main(){
//Poi q(0,1),w(1,0);
//double res=by(q,w,1,false);
double r;
Poi a,b,c,d;
cin>>r>>a>>b>>c>>d;
Poi m;
Poi A,B,C,D;
double chu1=chu(a.y,b.y,a.x,b.x),chu2=chu(c.y,d.y,c.x,d.x);
double b1=-chu1*b.x+b.y,b2=-chu2*d.x+d.y;
if(fabs(chu1)>INF){
m.x=a.x;
m.y=chu2*m.x+b2;
goto here;
}else if(fabs(chu2)>INF){
m.x=c.x;
m.y=chu1*m.x+b1;
goto here;
}
get(m,chu1,-1,chu2,-1,-b1,-b2);
here:
if(fabs(chu1)>INF){
A.x=B.x=m.x;
A.y=sqrt(r*r-A.x*A.x);
B.y=-sqrt(r*r-B.x*B.x);
}else solve(A,B,1+chu1*chu1,2*b1*chu1,b1*b1-r*r,chu1,b1);
if(fabs(chu2)>INF){
C.x=D.x=m.x;
C.y=sqrt(r*r-C.x*C.x);
D.y=-sqrt(r*r-D.x*D.x);
}else solve(C,D,1+chu2*chu2,2*b2*chu2,b2*b2-r*r,chu2,b2);
double s[6];
Poi o(0,0);
s[1]=sq(m,A,C)+by(A,C,r,bl(A,C,o,m));//若m在线外,要减
s[2]=sq(m,A,D)+by(A,D,r,bl(A,D,o,m));
s[3]=sq(m,B,C)+by(B,C,r,bl(B,C,o,m));
s[4]=sq(m,B,D)+by(B,D,r,bl(B,D,o,m));
sort(s+1,s+5);
printf("%.10f\n",s[4]);
return 0;
}