链接:http://vjudge.net/problem/viewProblem.action?id=49409
题意:一般的时钟是12小时制的,现给你一个H小时制的时钟,分钟、秒针还是60步一圈,然后给你一个时刻,问当前时刻开始,到哪一时刻秒针的秒针平分时针和分针的夹角,输出这一时刻的时间,秒用分数来表示。
OE大帝的博客讲的挺清楚了:http://blog.csdn.net/ooooooooe/article/details/37931707
在他的基础上我再补充几个我没看明白的地方
首先计算时针分针秒针当前转动角度,记整个表盘总角度为1.
设经过HH表示小时,MM表示分钟,SS表示秒,ss表示经过的时间,k是一个整数,它可能为0,但是有必要加上,现在的公式如下:
2 * ( SS + ss) + k = HH + MM; //①
为什么要加一个k,我用visio画了个图,有点丑,明白意思就行。
现假设a是秒针的角度,b是分针的角度,c是时针的角度,显然 a * 2 != b + c,因为他刚刚经过了0点,角度减少了360度。
设表盘总角度为1,此时 1 - c + a = b - a → 2a + 1 = b + c
所以要加一个k,补圈,而只要此时指针没有重合的就得到了答案。
把之前推得的角度代入① 式,得:
120 * s * H + 2 * ss + k * 3600H = 3600 * h + 60 * m + s + 60 * m * H + s * H
化简得:
( 119H - 1 ) * ( s + ss ) + k * 3600H= 3600h + 60m + 60mH
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 810 #define eps 1e-7 #define INF 0x7FFFFFFF #define long long ll; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int main(){ int H,h,m,s,i; while(scanf("%d%d%d%d",&H,&h,&m,&s),H||h||m||s){ int hh = 3600 * h + 60 * m + s; int mm = 60 * m * H + s * H; int ss = 60 * s * H; int K = 3600 * H; int sa = mm + hh - ss * 2; sa = (sa % K + K) % K; int c = 119 * H - 1; while(1){ int ct = c; int ssa = sa; int tt = __gcd(ct,ssa); ct/=tt; ssa/=tt; int ansh = (h+(m+(ct*s+ssa)/(ct*60))/60)%H; int ansm = (m+(ct*s+ssa)/(ct*60))%60; int anss = (ct*s+ssa)%(ct*60); if((3600*ansh+60*ansm)*ct+anss!=60*ansm*ct*H*anss*H){ printf("%d %d %d %d\n",ansh,ansm,anss,ct); break; } sa += K; } } return 0; }