一个很绕的计算题
它的意思就是你输入一个角度D,算出三个时针两两之间的角度都要比D大(最小的D),它们才会happy
我们可以通过计算捋一下逻辑:
秒钟的速度: 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
需要相差的角度为D。
至于周期的处理,我们可以从1s开始到1360012s
rsm>D → Dsm+k1tsm < t < tsm-Dsm+k1tsm;
rsh>D → Dsh+k2tsh < t < tsh-Dsh+k2tsh;
rmh>D → Dmh+k3tmh < t < tmh-Dmh+k3tmh;
k1k2k3是用来循环周期的,刚开始不是很明白为什么是 tsm-D*sm
解释啦.png
三个条件都满足所占的总时间即为时针、分针、秒针相差角度大于n的总时间
#include
#include
using namespace std;
int total=12*60*60;
double sm=10/59,sh=120/719,mh=120/11;//相差1°的时间
int main()
{
int t;
double D,max,min;
while(1)
{
int happyTicks=0;
scanf("%lf",&D);
if(D<0)
break;
min=D,max=360-D;
for(int i=0;i
{
if(i<4)
printf("%lf,%lf,%lf\n",sm*double(i),sh*double(i),mh*double(i));
if(min<=sm*double(i)&&sm*double(i)<=max&&min<=sh*double(i)&&sh*double(i)<=max&&min<=mh*double(i)&&mh*double(i)<=max)
happyTicks++;
}
printf("%lf\n",(double)happyTicks/total*100);
}
return 0;
}
但是这么做会超时,然后我就放弃了,去找了discuss
秒钟的速度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 → nsm+k1tsm < t < tsm-nsm+k1tsm; *
rsh>n → nsh+k2tsh < t < tsh-nsh+k2tsh; *
rmh>n → nmh+k3tmh < t < tmh-nmh+k3tmh; *
三个条件都满足所占的总时间即为时针、分针、秒针相差角度大于n的总时间 *
#include
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;
//43200究竟是怎么来的,这三层循环之间是怎么扯上关系的?
//43200是因为只算了12小时,12小时所占的比例就相当于24小时所占的比例
//通过两两是否重合来判断
for(ft3=fmh,et3=emh;et3<=43200;et3+=tmh,ft3+=tmh)
{
for(ft2=fsh,et2=esh;et2<=43200;et2+=tsh,ft2+=tsh)
{
if(et2
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
continue;
if(ft1>et3 || ft1>et2)
break;
begin=max(ft1,ft2,ft3)
sum+=min-max;
}
}
}
sum/=432.; // 为什么还有除以432?因为要算概率呀sum/43200*100%
printf("%.3lfn",sum);
}
}
#include
#include
#include
#include
using namespace std;
// 秒针速度 s = 6°/s 分针速度 m = 1/10° /s 时针 h = 1/120° /s
const double SH = 719.0/120, SM = 59.0/10, MH = 11.0/120;
const double tSH = 43200.0/719, tSM = 3600.0/59, tMH = 43200.0/11;
double Min(double a,double b,double c)
{
return min(a,min(b,c));
}
double Max(double a,double b,double c)
{
return max(a,max(b,c));
}
int main()
{
double D;
while(cin >> D && D!=-1)
{
double bSH,bSM,bMH,eSH,eSM,eMH,Begin,End,Sum = 0;
bSH = D / SH;
bSM = D / SM;
bMH = D / MH;
//计算第一次满足条件的时间(开始时间)
eSH = (360-D)/SH;
eSM = (360-D)/SM;
eMH = (360-D)/MH;
//计算第一次不满足条件的时间(结束时间)
for(double b3 = bSH,e3 = eSH; e3 <= 43200.000001; b3+=tSH,e3+=tSH)
{
for(double b2 = bMH,e2 = eMH; e2 <= 43200.000001; b2+=tMH,e2+=tMH)
{
if(e2 < b3) //判断是否有交集 就是要求有交集
continue; // 判断的话是根据for循环的内外顺序,如果内侧end小于外侧begin还是有机会超过的
if(b2 > e3) //三个循环交换顺序都是可以的
break;
for(double b1 = bSM,e1 = eSM; e1 <= 43200.000001; b1+=tSM,e1+=tSM)
{
if(e1 < b2 || e1 < b3)
continue;
if(b1 > e2 || b1 > e3)
break;
Begin = Max(b1,b2,b3); //开始时间取最大,以满足全部要求
End = Min(e1,e2,e3); //结束时间取最小,以满足全部要求
Sum += (End-Begin);
}
}
}
printf("%.3lf\n",Sum/432);
}
return 0;
}