如果直接按秒模拟的话,结果精度不够!
但可以按1/10秒模拟,精度就够了,但是会超时!
#include <iostream>
但可以按1/10秒模拟,精度就够了,但是会超时!
#include <iostream>
#include <iomanip>
#include <cmath>
#define MT (12*36000)
using namespace std;
int isD(double a,double b,int D)
{
double k=fabs(a-b);
if(k<=180)
{
if(k>=D) return 1;
}
else if(k>180)
{
double big=max(a,b);
if((360-big+(a+b-big))>=D) return 1;
}
return 0;
}
int main()
{
int D;
cin>>D;
while(D!=-1)
{
int tot=0;
double r=0,t=0,y=0;
for(int i=0;i<MT;i++)
{
int a=0,b=0,c=0;
r=r+1.0/1200;
t=t+0.01;
y=y+0.6;
while(y-360.0>1e-6)
{
y-=360.0;
}
while(t-360.0>1e-6)
{
t-=360.0;
}
a=isD(t,y,D);
b=isD(y,r,D);
c=isD(t,r,D);
if(a&&b&&c) tot++;
}
cout<<setiosflags(ios::showpoint)<<setiosflags(ios::fixed)<<setprecision(3)<<tot*100/(double)MT<<endl;
cin>>D;
}
return 0;
}
正确的方法是算出各个符合条件的集合的交集:(来自网上)
/***************************************************************************
/***************************************************************************
* *
*秒钟的速度s=6°/s,分针是1/10°/s,时针是1/120°/s *
*所以相对速度s_m=59/10°/s,s_h=719/120°/s,m_h=120/11°/s *
*所以相差一度所需要的时间sm=10/59 s/°,sh=120/719 s/°,mh=120/11 s/° *
*他们差360°的周期为tsm=3600/59 s,tsh=43200/719 s,tmh=43200/11 s *
*需要相差的角度为n。 *
*rsm>n → n*sm+k1*tsm < t < tsm-n*sm+k1*tsm; *
*rsh>n → n*sh+k2*tsh < t < tsh-n*sh+k2*tsh; *
*rmh>n → n*mh+k3*tmh < t < tmh-n*mh+k3*tmh; *
*三个条件都满足所占的总时间即为时针、分针、秒针相差角度大于n的总时间 *
* *
***************************************************************************/
#include<stdio.h>
void main()
{
int t;
double n,sum,ft1,ft2,ft3,et1,et2,et3,max,min;
double sm,sh,mh,tsm,tsh,tmh,fsm,fsh,fmh,esm,esh,emh;
sm=10./59.;
sh=120./719.;
mh=120./11.;
tsm=360*sm;
tsh=360*sh;
tmh=360*mh;
while(scanf("%lf",&n))
{
if(n<0)
break;
sum=0;
fsm=sm*n;
fsh=sh*n;
fmh=mh*n;
esm=tsm-fsm;
esh=tsh-fsh;
emh=tmh-fmh;
for(ft3=fmh,et3=emh;et3<=43200;et3+=tmh,ft3+=tmh)
{
for(ft2=fsh,et2=esh;et2<=43200;et2+=tsh,ft2+=tsh)
{
if(et2<ft3)
continue;
if(ft2>et3)
break;
for(t=0,ft1=fsm,et1=esm;et1<=43200;t=t+1,et1=esm+t*tsm,ft1=fsm+t*tsm)
{
if(et1<ft3 || et1<ft2)
continue;
if(ft1>et3 || ft1>et2)
break;
max=ft1;
if(ft2>max)
max=ft2;
if(ft3>max)
max=ft3;
min=et1;
if(et2<min)
min=et2;
if(et3<min)
min=et3;
sum+=min-max;
}
}
}
sum/=432.;
printf("%.3lf\n",sum);
}
里有个图,可以看下。