ACM题解报告——HD1006
今天解了一道杭电上的1006题:http://acm.hdu.edu.cn/showproblem.php?pid=1006
题目的大体意思就是讲,时钟上的时针、分针、秒针都想远离彼此,当三种针间的角度差都至少是给定的D角度时,称为happytime,最后需要输出一天内happytime所占的比例。解决该题的基本思想就是进行12小时即720分钟的happytime的暴力搜索,算出的总秒数除以720*60即最后的比例。
1、最开始拿到这个问题的时候,感觉有点无从下手,因为三种针每秒都在动着,我们可以选择一个标准,就是12时为0度,三种针的角速度都可以求出:时针:1/120 度/秒,分针:0.1 度/秒,秒针:6 度/秒,那么假使此刻为h时m分s秒,时针、分针、秒针的角度分别为30*h+0.5*m+1/120*s、6*m+0.1*s、6*s。
2、按照题目的意思,会给定一个角度D,而三种针两两之间的角度差必须要大于D,也就是解不等式
D<|angle|<360-D,分别解出不等式,再求它们之间的交集。
#include<stdio.h>
#include<stdlib.h>
/*h时m分s秒这一时刻的时针、分针、秒针的角度 */
#define hangle 30*h+0.5*m+1/120*s
#define mangle 6*m+0.1*s
#define sangle 6*s
/*三种针的转速*/
#define vh 1.0/120
#define vm 0.1
#define vs 6.0
int degree;
int s=0;
typedef struct //定义一个结构体用于储存不等式的解
{
double l;
double r;
}second;
second bargin(second a,second b)
{//函数bargin求交集
second c;
if(a.l>b.l )
c.l=a.l;
else
c.l=b.l;
if(a.r<b.r)
c.r=a.r;
else
c.r=b.r;
if(c.l>=c.r )
c.r=c.l=0;
return c;
}
second solve(double diff,double angle )
{//解不等式degree<|s*diff+angle|<360-degree
second ln;
if( diff>0 )
{
ln.l=(degree-angle)/diff;
ln.r=(360-degree-angle )/diff;
}
else
{
ln.l=(360-degree-angle )/diff;
ln.r=( degree-angle)/diff;
}
if( ln.l<0 )
ln.l=0;
if( ln.r>60 )
ln.r=60;
if( ln.r<=ln.l )
ln.r=ln.l=0;
return ln;
}
double happytime(int h,int m )
{
second ss[3][2];
double diff,angle;
second ln;
double result=0.0;
//hm 时针与分针之间满足happytime的秒数
diff=vh-vm;
angle=hangle-mangle;
ss[0][0]=solve( diff,angle );
ss[0][1]=solve( -diff,-angle );
//hs 时针与秒针之间满足happytime的秒数
diff=vh-vs;
angle=hangle-sangle;
ss[1][0]=solve( diff,angle );
ss[1][1]=solve(-diff,-angle );
//ms 分针与秒针之间满足happytime的秒数
diff=vm-vs;
angle=mangle-sangle;
ss[2][0]=solve( diff,angle );
ss[2][1]=solve(-diff,-angle );
int k,p,n;
/*注意下面这里的思想,绝对值不等式解出的区间要取并集,例如ss[0][0]与ss[0][1]间取并;而三个不同的表达式之间要取交集,即 ss[0][]与ss[1][]之间要取交集的 */
for( k=0;k<2;k++ )
for( p=0;p<2;p++ )
for( n=0;n<2;n++ )
{
ln=bargin( bargin(ss[0][k],ss[1][p]),ss[2][n] );
result+=( ln.r-ln.l );
}
return result;//返回每分钟内的happytime秒数
}
int main()
{
int h,m;
while(scanf("%ld",°ree)&°ree!=-1 )//输入-1结束
{
double result=0;
for(h=0;h<12;h++ )
for(m=0;m<60;m++ )
{
result+=happytime( h,m );
}
printf( "%.3lf\n",result*100.0/43200 );//最后的结果是输出比例
}
return 0;
}
杭电测试通过