UvaLive--6664--Clock Hands【模拟】

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值