标签:
0 120 90 -1
100.000 0.000 6.251
由于要记录连续时间,那么就利用区间记录,[begin,end]。另外,就拿时针和分针来做例子吧。时针的角速度为w_h=360.0/12*60*60=1.0/120,分针的角速度为w_m=360.0/60*60=1.0/10。两者的相对角速度为w_hm=w_m-w_h,“相对周期”为T_hm=360.0/w_hm。所谓的相对周期就是时针和分针出现重复的相对关系的最小时间。
这样的话就可以把时针和分针,时针和秒针,分针和秒针各自满足条件的集合求交集。显然,代码中利用的是三个for循环来暴力解决。不过有些显然不满足条件的情况即可去除,以减少计算次数。
x[3]和y[3]记录的是第一个开始满足条件的时间和第一个开始不满足条件的时间。m[3],n[3]则是分表根据相对周期来扩大x[3],y[3]以获得所有满足条件的时间集合,并求交集。
#include <iostream> #include <cstdio> using namespace std; //const double w_h=1.0/120,w_m=1./10,w_s=6.0; //角速度,时分秒 const double hm=11.0/120,hs=719.0/120,sm=59.0/10;//相对角速度,时分,时秒,分秒 const double T_hm=43200.0/11,T_hs=43200.0/719,T_sm=3600.0/59;//相对周期,相对周期就是时针和分针出现重复的相对关系的最小时间。 double Max(double a,double b,double c) { double temp = (a > b) ? a : b; return (temp > c) ? temp : c; } double Min(double a,double b,double c) { double temp = (a < b) ? a : b; return (temp < c) ? temp : c; } int main() { double degree; double x[3],y[3];//记录的是第一个开始满足条件的时间和第一个开始不满足条件的时间 double m[3],n[3];//根据相对周期来扩大x[3],y[3]以获得所有满足条件的时间集合,并求交集 double Begin,End,sum; while(scanf("%lf",°ree),degree != -1) { x[0] = degree / hm;//第一次满足条件的时间 x[1] = degree / hs; x[2] = degree / sm; y[0] = (360 - degree) / hm;//第一个开始不满足时间的条件 y[1] = (360 - degree) / hs; y[2] = (360 - degree) / sm; sum = 0.0; //求(m[0],n[0),(m[1],n[1]),(m[2],n[2])的重复部分 for(m[0] = x[0],n[0] = y[0];n[0] <= 43200.000001;m[0] += T_hm,n[0] += T_hm) { for(m[1] = x[1],n[1] = y[1];n[1] <= 43200.000001;m[1] += T_hs,n[1] += T_hs) { if(n[0] < m[1]) //说明(m[0],n[0),(m[1],n[1])不相交 break; if(m[0] > n[1]) //(m[1],n[1])比(m[0],n[0])小,继续增加可能相交 continue; for(m[2] = x[2],n[2] = y[2];n[2] <= 43200.000001;m[2] += T_sm,n[2] += T_sm) { if(n[0]<m[2] || n[1]<m[2]) break; if(m[0]>n[2] || m[1]>n[2]) continue; Begin = Max(m[0],m[1],m[2]); End = Min(n[0],n[1],n[2]); if(End > Begin) sum += End - Begin; } } } printf("%.3lf\n",sum * 100.0 / 43200); } return 0; }
标签:
原文地址:http://blog.csdn.net/qq_29807167/article/details/51355189