训练赛 blot
来源:互联网 发布:洛瑞16赛季场均数据 编辑:程序博客网 时间:2024/05/29 11:23
- 题面
- 题目大意
- 输入格式
- 输出格式
- 数据范围
- 题解
- 代码
题面
题目大意
在地球和太阳之间有一个绕地心公转,绕其自身重心自转的干扰器。干扰器会遮挡阳光。我们将太阳视为一个点光源,地球视为一个圆,而干扰器是一个简单多边形。现在询问在某一时刻,地球上被阳光照射的区域的长度(即圆上被照射到的弧的长度).
输入格式
第一行五个整数,
第二行四个整数,
接下来n行,每行两个整数x,y.按顺时针或逆时针顺序给出干扰器上的n个点.
输出格式
一行,一个实数表示答案,保留两位小数。
数据范围
题解
其实就是一个模拟。不需要用到什么重要的算法,只是要注意一些细节问题.
- 重心的求法?
- 将多边形剖分成若干个三角形,每个三角形求一次重心。之后以三角形有向面积为权重,求这些重心的加权平均数即可。
举个例子:求梯形A(0,0),B(0,12),C(12,12),D(24,0)的重心:
1.剖分为三角形ABC与三角形ACD.
2.重心分别为:(4,8)与(12,4).
3.权重(有向面积):-72与-144
4.重心坐标(x,y)满足:x=4∗(−72)+12∗(−144)(−72)+(−144)=283 y=8∗(−72)+4∗(−144)(−72)+(−144)=163 - 如果是凹多边形怎么办?
- 这个没有关系,因为我们是用的有向面积。
- 公转自转的处理?
- 利用转轴公式。如果记不住的话,可以利用复平面知识现推:
(x+yi)(cosϕ+isinϕ)=(xcosϕ−ysinϕ)+(xsinϕ+ycosϕ)i,其中i为虚数单位. - 旋转的问题:
- 先计算出各点与重心的相对位置,记作向量
pi - 将
pi 按照规定角度旋转,得到p′i - 旋转重心
g - 计算
g+p′i 即得到各点的位置. - 注意不要先绕重心旋转再绕地心旋转,那样干扰器上各点的自转角度其实变大了。
- 先计算出各点与重心的相对位置,记作向量
- 利用转轴公式。如果记不住的话,可以利用复平面知识现推:
- 覆盖问题的处理
- 遍历所有点,以太阳为基准,按极角排序?
- 是不是一定要排序?是否可以只取最大值与最小值?
- atan2的值变化不连续,第二象限角和第三象限角对应的函数值有突变,故不能单纯地取最大值与最小值。
- 但是我们可以事先将太阳转到x负半轴上,那么所有合法的角必然落在第一象限与第四象限。这样就可以简单地取最值了。
- 注意地球背面的点不能算在内
- 计算光线与地球交点的圆心角时,建议利用垂径定理,简化运算。
- 精度问题:我们要相信cmath库中的函数都是算得很准的。额,其实这个就算是有精度差,我也无能为力。据说有大佬把地球分成了一百万个小段来处理,以取得更高的精度,这种做法我实在不会。
代码
变量名很乱
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const double pi=3.1415926535897932384626433832795;//这个可以用windows自带的计算器算void _r(int& x,bool f=0){ char c=getchar(); while(c<'0'||c>'9') { f|=(c=='-'); c=getchar(); } for(x=0;c>='0'&&c<='9';c=getchar()) { x=(x<<1)+(x<<3)+c-'0'; } x=f?-x:x; return ;}//输入优化struct point//点,向量{ double x,y; point(double a=0,double b=0) { x=a; y=b; } point operator + (point b) { return point(x+b.x,y+b.y); } point operator - (point b) { return point(x-b.x,y-b.y); } double operator * (point b) { return x*b.y-y*b.x; } point rot(double A) { double si=sin(A),co=cos(A); return point(x*co-y*si,x*si+y*co); }//转轴,弧度制 void print() { printf("%.2lf %.2lf \n",x,y); }//调试语句};inline double Area(point a,point b,point c){ return (b-a)*(c-a);}//有向面积point earth,sun,p[50],cen;double R;int T1,T2,T;//公转,自转,time; int n,X,Y;point cal(){ if(n==1) { return p[1]; } if(n==2) { return point((p[1].x+p[2].x)/2.0,(p[1].y+p[2].y)/2.0); } double summ=0,_x=0,_y=0,_s=0,tx,ty; for(int i=2;i<n;i++) { _s=Area(p[1],p[i],p[i+1]); tx=(p[1].x+p[i].x+p[i+1].x)/3.0; ty=(p[1].y+p[i].y+p[i+1].y)/3.0; _x+=tx*_s; _y+=ty*_s; summ+=_s; } return point(_x/summ,_y/summ);}//求重心const double eps=1e-7;double solve(double A){ if(A<0) { return -pi/2.0-A+acos(sun.x*sin(A)/R); } else { return pi/2.0-A-acos(-sun.x*sin(A)/R); }}//计算交点的圆心角,垂径定理int main(){ //freopen("blot.in","r",stdin); //freopen("blot.out","w",stdout); _r(X); _r(Y); sun=point(1.0*X,1.0*Y); _r(X); _r(Y); earth=point(1.0*X,1.0*Y); sun=sun-earth; double angle=atan2(sun.y,sun.x); angle=pi-angle; sun=sun.rot(angle); _r(X); R=1.0*X; _r(n); scanf("%d%d%d",&T1,&T2,&T); for(int i=1;i<=n;i++) { _r(X); _r(Y); p[i]=point(1.0*X,1.0*Y); p[i]=p[i]-earth; p[i]=p[i].rot(angle); } cen=cal(); int t1=T%T1,t2=T%T2; angle=2*pi*t2/(1.0*T2); point tmp; for(int i=1;i<=n;i++) { tmp=p[i]-cen; p[i]=tmp.rot(angle); } angle=2*pi*t1/(1.0*T1); cen=cen.rot(angle); for(int i=1;i<=n;i++) { p[i]=p[i]+cen; } double lim,cenA,mx,mn,S; cenA=asin(R/-sun.x);//阳光的范围,圆心角 S=pi*R-2*cenA*R;//无遮挡情况下的照射弧长 mx=-cenA; mn=cenA; lim=R*R/sun.x; for(int i=1;i<=n;i++) { if(p[i].x<lim) { tmp=p[i]-sun; angle=atan2(tmp.y,tmp.x); mx=max(mx,angle); mn=min(mn,angle); } } double L=0,a1,a2; mx=min(cenA,mx); mn=max(-cenA,mn); if(mx>mn) { a1=solve(mn); a2=solve(mx); L=(a2-a1)*R; } printf("%.2lf\n",S-L); return 0;}
阅读全文
0 0
- 训练赛 blot
- Western Blot
- Southern Blot & Northern Blot
- Anti-Blot System
- 【Storm 入门】 Blot分流
- soj 1757. Anti-Blot System
- 解析BLOT例子——HelloBolt5
- 训练赛
- 训练集--训练赛8
- 训练集---训练赛9
- 训练集---训练赛10
- 训练集---训练赛11
- 训练集---训练赛12
- 训练集---训练赛13
- 训练集---训练赛14
- 使用 matplotlib 绘制western blot表达量柱状图
- 寒假训练---训练赛2--Fighting
- 寒假训练--训练赛2--Good Luck!
- 音视频数据处理(-1) BMP格式详解
- maven国内服务器
- 加载插件(四)之动态加载
- android parceble序列化问题
- LOVE2D 简易生成Android的APK
- 训练赛 blot
- Powershell快速入门(三) 实战应用
- Giraph添加计数器的几个关键类
- Windows图形设备接口(GDI)及Windows绘图
- IMWeb提升营Day5
- A20 android4.2.2开机自启以太网
- ARM学习笔记5-S5pv210开发板启动
- HA 场景下访问 HDFS JAVA API Client
- php curl踩到的一个坑