Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6204 Accepted Submission(s): 1687
首先想到的是一秒一秒的试。
/**
* 采用离散的点,精度无法满足
*/
#include
int is(double h,double m,double s,int d){
double hs,hm,ms;
hs=h>s?h-s:s-h;
hm=h>m?h-m:m-h;
ms=m>s?m-s:s-m;
if(hs>180)hs=360-hs;
if(hm>180)hm=360-hm;
if(ms>180)ms=360-ms;
if(ms>=d&&hs>=d&&hm>=d)return 1;
return 0;
}
int main(){
int d,c,t;
double h,m,s;
while(scanf("%d",&d),~d){
t=c=h=m=s=0;
for(;t<3600*12;t++){
s+=6;
m+=1.0/10;
h+=1.0/120;
if(s>=360)s-=360;
if(m>=360)m-=360;
if(h>=360)h-=360;
if(is(h,m,s,d))c++;
}
printf("%.3f\n",c*2/864.00);
}
}
做了好久无果,参考大神的代码,原来用角速度,然后暴力搜索720min。
/**
* @date 2013-2
* @name Tick and Tick
* 用角速度
*/
#include
#include
#include
#include
#define V_SEC 6.0 //秒针角速度
#define V_MIN 0.1 //分针角速度
#define V_HOU 1.0/120 //时针角速度
#define A_SEC s*6 //秒针角度
#define A_MIN m*6+s*0.1 //分针角度
#define A_HOU h*30+m*0.5+s/120.0 //时针角度
using namespace std;
struct interval{ //区间
double l; //left
double r; //right
};
double Angle; //角度
int s=0; //秒数
interval solve(double v,double a){//解方程
//Angle<=v*t+a<=360-Angle;,并且和[0,60]取交集
interval p;
if(v>0){
p.l=(Angle-a)/v;
p.r=(360-Angle-a)/v;
}
else{
p.l=(360-Angle-a)/v;
p.r=(Angle-a)/v;
}
if(p.l< 0)p.l= 0;
if(p.r>60)p.r=60;
if(p.l>=p.r)p.l=p.r=0;
return p;
}
interval jiao(interval a,interval b){
interval p;
p.l=max(a.l,b.l);
p.r=min(a.r,b.r);
if(p.l>=p.r)p.l=p.r=0;
return p;
}
/*
hh=30*h+m/2+s/120
mm=6*m+s*0.1
ss=6*s
Angle<=|hh-mm|<=360-Angle
Angle<=|hh-ss|<=360-Angle
Angle<=|mm-ss|<=360-Angle
*/
double happytime(int h,int m){//计算h时m分 满足题意的秒数
double v_diff;//速度差
double a_diff;//角度差
interval s0[3][2];
interval s1;
/*解方程 Angle<=|hh-mm|<=360-Angle*/
v_diff=V_HOU-V_MIN;
a_diff=A_HOU-A_MIN;//时针分针夹角
s0[0][0]=solve( v_diff, a_diff);
s0[0][1]=solve(-v_diff,-a_diff);
/*解方程 Angle<=|hh-ss|<=360-Angle*/
v_diff=V_HOU-V_SEC;
a_diff=A_HOU-A_SEC;//时针秒针夹角
s0[1][0]=solve( v_diff, a_diff);
s0[1][1]=solve(-v_diff,-a_diff);
/*解方程 Angle<=|mm-ss|<=360-Angle*/
v_diff=V_MIN-V_SEC;
a_diff=A_MIN-A_SEC;//分针秒针夹角
s0[2][0]=solve( v_diff, a_diff);
s0[2][1]=solve(-v_diff,-a_diff);
/*
六个区间,选三个取交集
因为绝对值的式子得到的两个区间要并,而三个不同表达式
的区间要交,故这样做
*/
double res=0;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++){
s1=jiao(jiao(s0[0][i],s0[1][j]),s0[2][k]);
res+=s1.r-s1.l;
}
return res;
}
int main(){
int h,m;
while(scanf("%lf",&Angle)){
if(Angle==-1)break;
double res=0;
for(h=0;h<12;h++)
for(m=0;m<60;m++)
res+=happytime(h,m);
printf("%.3lf\n",res*100.0/43200);
}
}