链接: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;
}