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",&degree)&&degree!=-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; }

 

杭电测试通过

你可能感兴趣的:(ACM)