時針分針與秒針

来源:https://www.cnblogs.com/cs-whut/archive/2022/12/06/16953179.html
-Advertisement-
Play Games

本文使用Python實現『顏色提取』功能,構建『簡單提取器』與『複雜提取器』,從單個或多個圖像的某個位置提取顏色,類似PS或者PPT中的取色器功能。 ...


【例1】時針分針與秒針

問題描述

給定一個24小時格式的數字時間,問給定的這個時刻時針與分針、時針與秒針、分針與秒針 之間的夾角分別是多少?

輸入

 有T(1≤T≤104)組測試用例。

 對於每組測試用例,用一行hh:mm:ss描述給定的時間。0≤hh<24,0≤mm<60,0≤ss<60。

 輸出

 對於每組測試用例,輸出像A/B這樣的實數。(A和B是互質的)。如果它是一個整數,那麼就直接輸出它。描述時針和分針、時針和秒針、分針和秒針之間的角度。

輸入樣例 

4

00:00:00

06:00:00

12:54:55

04:40:00

輸出樣例

0 0 0

180 180 0

1391/24 1379/24 1/2

100 140 120

       (1)編程思路。

       將表盤的0點(或12點)作為起點,整個表盤轉一圈360度,用60個刻度線分成60格,每1格就是6度。

       時鐘每走1個小時,時針走5格,轉30度;分針走60格,轉360度(正好走一圈,相當轉0度);秒針走3600格,轉21600度(走了60圈,也相當轉0度)。

       時鐘每走1分鐘,分針走1格,轉6度;時針走5/60格,轉1/2度;秒針走60格,相當轉了0度。

       時鐘每走1秒,秒針走1格,轉6度;分針走1/60格,轉1/10度;時針走5/3600格,相當轉了1/120度。

       因此,對於任意一個時刻hh:mm:ss,有

       時針轉的度數為 30*hh + 1/2*mm + 1/120*ss

       分針轉的度數為 6*mm + 1/10*ss

       秒針轉的度數為 6*ss

       計算出各指針轉的度數後,它們之間的差值就是它們的夾角。

       由於計算時有分數比1/120,將它們都乘以120(相當於通分,分母為120),這樣只看各分子部分。有

       時針轉的度數為 3600*hh + 60*mm + ss

       分針轉的度數為 720*mm + 12*ss

       秒針轉的度數為 720*ss

       (2)源程式。

#include <stdio.h>
int gcd(int a,int b)
{
    if (a%b==0) return b;
    else return  gcd(b,a%b) ;
}
void output(int a,int b)   //  計算圓盤上轉過a度和b度的兩指針之間的夾角並輸出
{
    int x;
    x=a>b? a-b:b-a ;
    if (x % 120 == 0)
    {
        x /= 120 ;
        x %= 360 ;
        if (x%360 == 0 )
            printf("0 ") ;
        else if (x%180 == 0 )
            printf("180 ") ;
        else
            printf("%d ", x<180?x:360-x) ;
    }
    else
    {
        x=x%43200;
        if (x>43200-x)    // 通分後,圓盤一周360度變成 43200度(360*120)
            x=43200-x;
        int k = gcd(x,120) ;
        printf("%d/%d ", x/k, 120/k) ;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        int h,m,s,x,y,z;
        scanf("%d:%d:%d", &h, &m, &s) ;
        x = 3600*h + 60*m + s ;
        y = 720*m + 12*s ;
        z = 720*s ;
        output(x,y);
        output(x,z);
        output(y,z);
        printf("\n") ;
    }
    return 0;
}

       將上面的源程式提交給HDU 題庫 HDU 5387 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=5387),可以Accepted。

       將上面的源程式略作修改,還可以提交給 HDU 2076 夾角有多大 (http://acm.hdu.edu.cn/showproblem.php?pid=2076)。

【例2】時針與分針的夾角

 問題描述

給定一個時間HH:MM:SS和一個參數a,請你計算滿足以下條件的下一個時間:

1.時針和分針形成的角度是a。

2.時間可以不是整數,但向下舍入。例如12:34:56.78向下舍入為12:34:56。

 輸入

輸入包含多個測試用例。

每個測試用例包含兩行。

第一行是時間HH:MM:SS(0≤HH<12,0≤MM<60,0≤SS<60)。

第二行包含一個整數a(0≤a≤180).

輸出

對於每個測試用例,輸出一行包含測試用例編號和答案HH:MM:SS。

輸入樣例

0:59:59

30

01:00:00

30

輸出樣例

Case #1: 01:00:00

Case #2: 01:10:54

       (1)編程思路。

       對給定的時間,一秒一秒的加1(向前走一秒到下一個時間)進行枚舉,每次枚舉一個時間,計算時針與分針的夾角r,若r正好等於a,輸出當前時間並結束枚舉。若r不是正好等於a,則輸出找到的第1個形成夾角大於a的前一秒。為此,程式中用pr保存前1秒時間(ph:pm:ps)指針與分針的夾角,這樣當前一秒的夾角pr小於a,但後一秒的夾角大於a,即pr!=a && (pr-a)*(r-a)<0時,輸出前1秒時間ph:pm:ps即可。

       (2)源程式。

#include <stdio.h>
int main()
{
    int iCase=0;
    int h,m,s;
    while (scanf("%d:%d:%d",&h,&m,&s)!=EOF)
    {
        int a;
        scanf("%d", &a) ;
        int ph=h,pm=m,ps=s;
        double r,pr;
        pr=(3600*h + 60*m + s-720*m - 12*s+43200)%43200/120.0;
        if (pr > 180) pr=360-pr;
        while (1)
        {
            s++;
            if (s>=60)
            {
                s=s%60;
                m++;
                if (m>=60)
                {
                    m=0; h=(h+1)%12;
                }
            }
            r=(3600*h + 60*m + s-720*m - 12*s+43200)%43200/120.0;
            if (r > 180) r=360-r;
            if (r==a)
            {
                printf("Case #%d: %02d:%02d:%02d\n",++iCase,h,m,s);
                break;
            }
            else if (pr!= a && (r-a) * (pr-a) < 0)
            {
                printf("Case #%d: %02d:%02d:%02d\n",++iCase,ph,pm,ps);
                break;
            }
            pr=r;
            ph=h;
            pm=m;
            ps=s;
        }
    }
    return 0;
}

        將上面的源程式提交給HDU 題庫 HDU 5705  Clock (http://acm.hdu.edu.cn/showproblem.php?pid=5705),可以Accepted。

【例3】時間復現

問題描述

小明有一個鐘錶,當前鐘錶指向了某一個時間。

又有一些很重要的時刻,小明想要在鐘錶上復現這些時間(並不需要依次復現)。我們可以順時針轉動秒針,也可以逆時針轉動秒針,分針和時針都會隨著秒針按規則轉動,小明想知道秒針至少轉動多少角度可以使每個時刻至少都會被訪問一次。

註意,時鐘上的一種時針分針秒針的組合,可以代表兩個不同的時間。

輸入

第一行一個整數 n 代表有多少個時刻要訪問。

第二行三個整數 h,m,s 分別代表當前時刻的時分秒。

最後n行每一行三個整數 hi,mi,si 代表每個要訪問的時刻的時分秒。

1 ≤ n ≤ 86, 400

0 ≤ h, hi < 24

0 ≤ m, mi, s, si < 60

輸出

輸出一行一個數代表秒鐘轉的角度,答案保留兩位小數。

輸入樣例

1

0 1 0

0 1 1

輸出樣例

6.00

       (1)編程思路。

       我們知道,每小時有3600秒,每分鐘有60秒,每秒秒針轉6度。因此,對於任意一個時刻hh:mm:ss來說,秒針一共會順時針轉(hh * 3600 + mm * 60 + ss)*6 度。

       先求出需要每個復現的時間相對當前時間需要順時針轉過的度數,並保存到數組rotate中。在將數組按照轉過的度數從小到大排序,即最小轉過的角度保存在rotate[1]中,最大轉過的角度保存在rotate[N]中。排序後,要復現N個時刻。可以在以下四種情況中取最小值即可。

       ①   秒針只順時針走。走到需要轉過的最大角度rotate[N]即可。

       ②   秒針只逆時針走。走到需要轉過的最小角度rotate[1]即可,由於是逆時針旋轉,實際轉過的角度等於aRound-rotate[1]。aRound為時鐘上時針轉完整一圈,秒針需要轉的度數360*60*12。

       ③   先順時針走到某個角度rotate[i],再逆時針走到其下一個角度rotate[i+1]。此時,秒針實際轉過的度數為 rotate[i] * 2 + (aRound - rotate[i + 1])。

       ④   逆時針走到某個角度rotate[i],再順時針走到其前一個角度rotate[i-1]。此時,秒針實際轉過的度數為 rotate[i-1] + (aRound - rotate[i])*2。

        (2)源程式。 

#include <stdio.h>
#include <algorithm>
using namespace std;
#define aRound 360 * 60 * 12                  // 時針轉一整圈(12小時),秒針轉過的度數
int main()
{
    int n;
    while (scanf("%d", &n)!=EOF)
    {
        int h,m,s,nowrot,tt;
        scanf("%d%d%d", &h, &m, &s);
        if (h >= 12)  h -= 12;
        nowrot = (h * 3600 + m * 60 + s)*6;   // 當前時刻秒針轉過的度數
        int i,rotate[86405];                  // 保存各時刻從當前時刻起 秒針順時針轉過的度數
        for (i = 1; i <= n; i++)
        {
            scanf("%d%d%d", &h, &m, &s);
            if (h >= 12) h -= 12;
            tt = (h * 3600 + m * 60 + s)*6;
            rotate[i] = tt - nowrot;
            if (rotate[i] < 0)
                rotate[i] += aRound;
        }
        sort(rotate + 1, rotate + n + 1);     // 將各時刻秒針轉過的度數從小到大排序
        int ans = aRound + 1000000;
        rotate[0] = aRound;
        rotate[n + 1] = aRound;
        if (ans>rotate[n]) ans=rotate[n];     // 秒針一直順時針轉過最大度數
        if (ans>aRound-rotate[1]) ans=aRound-rotate[1];   // 秒針一直逆時針轉過最小度數
        for (i = 1; i <= n; i++)              // 先順時針轉到某個度數,再逆時針轉到其下一個度數
        {
            tt=rotate[i] * 2 + (aRound - rotate[i + 1]);
            if (ans>tt) ans=tt;
        }
        for (i = 1; i <= n; i++)              // 先逆時針轉到某個度數,再順時針轉到其下一個度數
        {
            tt=rotate[i-1] + (aRound - rotate[i])*2;
            if (ans>tt) ans=tt;
        }
        printf("%d.00\n", ans);
    }
    return 0;
}

        將上面的源程式提交給HDU 題庫 HDU 6551 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=6551),可以Accepted。

【例4】時鐘

問題描述

從a點b分到s點t分時針和分針重合多少次?

輸入

有多組數據,每組1行4個數 a,b,s,t. 1<=a,s <=12, 0<=b,t<60。0 0 0 0結束。

輸出

每組測試用例,用1行輸出一個整數,表示分針與時針的相遇次數。

輸入樣例

12 50 1 2

3 8 3 20

2 45 11 0

11 0 3 20

1 2 12 50

3 20 3 8

0 0 0 0

輸出樣例

0

1

8

4

11

10

       (1)編程思路。

       本題主要看分針(相對時針)在這個時間段內可以迴圈多少圈,每迴圈一圈就是相遇一次。

       設初始時為00:00,此時分針與時針重合在一起。之後時針在走,分針也在走。每次分針比時針多走一圈,它們就會相遇一次(重合在一起一次)。

       對於任意一個時間hh:mm,我們需要計算分針相比時針多走幾圈。

       我們知道,12個小時,時針正好走1圈,而分針走了12圈(每1小時走1圈),相比時針,分針多走了12-1=11圈。也就是說在12小時(也是720分鐘)內,時針與分針會重合11次。即1分鐘會多走 11/720圈。

       對於時間hh:mm,分針比時針多走的圈數為 (hh*60+mm)*11/720。

       兩個時間的圈數差,就是這個時間段內分針與時針的相遇次數。

       (2)源程式。

#include <stdio.h>
int main()
{
    int a,b,s,t,ans;
    while (scanf("%d%d%d%d",&a,&b,&s,&t) && (a || b || s || t))
    {
        a=a%12;
        s=s%12;
        int s1=(a*60+b)*11;
        int s2=(s*60+t)*11;
        if (s2<s1) s2+=720*11;
        ans=s2/720-s1/720;    // 兩個時間的圈數差就是它們的相遇次數
        if (s1==0) ans++;     // 出發時相遇加1
        printf("%d\n",ans);
    }
    return 0;
 }

       將上面的源程式提交給HDU 題庫 HDU 2180 時鐘 (http://acm.hdu.edu.cn/showproblem.php?pid=2180),可以Accepted。

       在理解了時鐘上時針、分針和秒針轉動規律的基礎上,可以將HDU題庫中如下的幾道題目作為練習。

【練習1】HDU Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1209)。

// 按照時針與分針的夾角大小來排序
#include <stdio.h>
typedef struct
{
    int h,m;
    double r;    // 時針與分針的夾角
}Node;
int cmp(Node x,Node y)
{
    if (x.r!=y.r)  return x.r>y.r;
    if (x.h!=y.h) return x.h>y.h;
    return x.m>y.m;
}
double fabs(double x)
{
    return x>0?x:-x;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        Node a[5],temp;
        int i,j;
        for (i = 0;i<5;i++)
        {
            scanf("%d:%d",&a[i].h,&a[i].m);
            if (a[i].h>12)
                a[i].r = fabs(30.0*(a[i].h-12)+a[i].m/2.0-6.0*a[i].m);
            else
                a[i].r = fabs(30.0*a[i].h+a[i].m/2.0-6.0*a[i].m);
            if (a[i].r>180)
                a[i].r = 360-a[i].r;
        }
        for (i=0;i<5-1;i++)
            for (j=0;j<5-1-i;j++)
               if (cmp(a[j],a[j+1]))
               {
                  temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
               }
        printf("%02d:%02d\n",a[2].h,a[2].m);
    }
    return 0;
}
參考程式

【練習2】HDU 1371 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1371)。

#include <stdio.h>
int main()
{
    printf("Program 3 by team X\n");
    printf("Initial time  Final time  Passes\n");
    int a,b,s,t,ans;
    while (scanf("%d%d%d%d",&a,&b,&s,&t)!=EOF)
    {
        printf("       %02d:%02d       %02d:%02d",a,b,s,t);
        a=a%12;
        s=s%12;
        int s1=(a*60+b)*11;
        int s2=(s*60+t)*11;
        if (s2<s1) s2+=720*11;
        ans=s2/720-s1/720;    // 兩個時間的圈數差就是它們的相遇次數
        if (s1==0) ans++;     // 出發時相遇加1
        printf("%8d\n",ans);
    }
    printf("End of program 3 by team X\n");
    return 0;
 }
參考程式

【練習3】HDU 1393 Weird Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1393)。

#include <stdio.h>
int main()
{
    int s,d;
    while (scanf("%d%d",&s,&d) && (s||d))
    {
        if (s >= 60)
            s %= 60;
        int count = 0,flag = 1;
        while (s)
        {
            s += s*d;
            s %= 60;
            if(count > 1000)
            {
                flag = 0;
                break;
            }
            count++;
        }
        if (flag)
            printf("%d\n",count);
        else
            printf("Impossible\n");
    }
    return 0;
}
參考程式

【練習4】HDU 2395 Alarm Clock (http://acm.hdu.edu.cn/showproblem.php?pid=2395)。

#include <stdio.h>
#include <string.h>
int calc(int a,int b,int mod)
{
    int ans1,ans2;
    ans1=(a-b+mod)%mod;
    ans2=(b-a+mod)%mod;
    return ans1<ans2?ans1:ans2;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        char s1[8],s2[8];
        scanf("%s %s",s1,s2);
        int h1,m11,m12,h2,m21,m22;
        char c1,c2;
        if (s1[1]==':')
        {
           h1=s1[0]-'0';
           m11=s1[2]-'0';  m12=s1[3]-'0';
           c1=s1[4];
        }
        else
        {
           h1=(s1[0]-'0')*10+(s1[1]-'0');
           m11=(s1[3]-'0');  m12=s1[4]-'0';
           c1=s1[5];
        }
        if (s2[1]==':')
        {
           h2=s2[0]-'0';
           m21=(s2[2]-'0');  m22=s2[3]-'0';
           c2=s2[4];
        }
        else
        {
           h2=(s2[0]-'0')*10+(s2[1]-'0');
           m21=(s2[3]-'0');  m22=s2[4]-'0';
           c2=s2[5];
        }
        int cnt=0;
        if (c1!=c2)
            cnt++;
        cnt+=calc(h1,h2,12);
        cnt+=calc(m11,m21,6);
        cnt+=calc(m12,m22,10);
        printf("Going from %s to %s requires %d %s\n",s1,s2,cnt,(cnt==1)?"push.":"pushes.");
    }
    return 0;
}
參考程式

 【練習5】HDU 3248 Strange Clock (http://acm.hdu.edu.cn/showproblem.php?pid=3248)。

#include <stdio.h>
int main()
{
    int n,m;
    while (scanf("%d",&n) && n!=-1)
    {
        n = (n+270)%360;
        m = n / 30;
        m=12-m;
        if (n%30==0) printf("Exactly %d o'clock\n",m%12);
        else printf("Between %d o'clock and %d o'clock\n",(12+m-1)%12,m%12);
    }
    return 0;
}
參考程式
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 模板作為C++泛型編程的基礎十分重要,其使得一份代碼能用於處理多種數據類型。而有些時候,我們會希望對一些特定的數據類型執行不同的代碼,這時就需要使用模板特例化(template specialization)。 函數模板特例化 首先說一個重要的,函數模板的特例化並不是函數重載,每一個特例化實際上是提 ...
  • 概要 manim 是一個做數學視頻的 python 庫,這個庫功能非常強大。具體可以參考官方介紹:https://github.com/ManimCommunity/manim/ 它本身只是封裝數學相關的幾何體和一些基礎動畫,所以,製作視頻時,需要進一步封裝更複雜的動畫來滿足視頻的要求。最近做的一個 ...
  • 在我的客服系統項目中,我使用的gin框架沒有自帶session功能,需要經過下麵的整合處理 使用的是 github.com/gin-contrib/sessions 在我的tools包下 package tools import ( "github.com/gin-contrib/sessions" ...
  • 介面優化過程記錄 問題背景 某個介面耗時長(247ms),但裡面邏輯不算複雜,只進行了簡單的對象引用以及操作了多次Redis 步驟1:鏈路追蹤,確定業務耗時點 介面里通過鏈路追蹤以及日誌查詢發現主要是操作Redis的這條鏈路耗時變長 步驟2:從Redis找問題,列出可能點 原因可能是: Redis本 ...
  • Map的常用方法 案例1 場景:一張建行用戶體驗金信息大表(百萬級別),裡面存在一個欄位對多條數據,需要統計某個欄位的多條數據累加值以供於別的服務調用。 優化前解決:直接查出來一個大list給到另一個服務,再另外一個服務里有笛卡爾積算出累加值(笛卡爾積後得到jvm需運算56億次),程式直接接近崩潰, ...
  • JZ34 二叉樹中和為某一值的路徑(二) 描述 輸入一顆二叉樹的根節點root和一個整數expectNumber,找出二叉樹中結點值的和為expectNumber的所有路徑。 1.該題路徑定義為從樹的根結點開始往下一直到葉子結點所經過的結點 2.葉子節點是指沒有子節點的節點 3.路徑只能從父節點到子 ...
  • 上線流程 上線前準備 首先將跑在本地版本的項目,上傳至遠端(gitee、github上) 重新複製一份項目的配置文件,可以命名為pro.py(dev為開發階段的配置文件,pro為上線的配置文件) 在pro文件內,修改以下配置項: # 將調式模式改為false DEBUG = False # 運行的h ...
  • Redis數據結構 1. SDS Redis 是用 C 語言寫的,但是對於 Redis 的字元串,卻不是 C 語言中的字元串(即以空字元’\0’結尾的字元數組),它是自己構建了一種名為 簡單動態字元串(simple dynamic string,SDS)的抽象類型,並將 SDS 作為 Redis 的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...