三针重叠问题算法整理


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;


public class ThreeNeedleFolding {

    /**
     * 计算三针重叠方法一
     */
    public static void method01() {

        long base = new GregorianCalendar(0, 0, 0, 0, 0, 0).getTime().getTime();
        DateFormat df = new SimpleDateFormat("HH:mm:ss");
        // 一天有24小时60分60秒, 假设时钟有60格
        for (long t = 0L; t < 24 * 60 * 60; t++) {

            /*
             * 时针走完一圈才走了60*60*12秒,也即半天。除去60*60*12取余数是为了将后半天映射到时钟面上去
             * 
             * 时针60分钟走5个格子, 12分钟走1格子,也即60*12秒走一格子,除以60*12可以得到此刻时针在哪一格
             */
            long hourHand = Math.round((t % (60 * 60 * 12)) / (60 * 12));

            /*
             * 分针走完一圈才走了60*60秒。总秒数除以60*60取余数是为了将特定时刻映射到时钟面上去
             * 
             * 分针60秒走1格子,除以60可以得到分针此刻处于哪一个格子
             */
            long minuteHand = Math.round((t % (60 * 60)) / 60);

            /*
             * 秒针走完一圈才走了60秒,总秒数除以60取余数是为了将特定时刻映射到时钟面上去
             * 
             * 秒针1秒走1格子,除以1可以得到秒针此刻处于哪一个格子
             */
            long secondHand = t % 60;
            if (hourHand == minuteHand && minuteHand == secondHand) {
                // Date对象以毫秒为单位构造实例
                Date date = new Date(base + t * 1000);
                System.out.println(df.format(date));
            }
        }

    }

    /**
     * 计算三针重叠方法二,假设时钟有60格
     */
    public static void method02() {
        int ch = 0;
        int h = 0;
        int m = 0;
        int s = 0;
        StringBuffer sb = new StringBuffer();
        for (h = 0; h <= 12; h++) {
            for (m = 0; m <= 60; m++) {
                for (s = 0; s <= 60; s++) {
                    // 分针每走12小格,时针走一小格。时针每两个时刻之间间隔5个小格
                    ch = h * 5 + m / 12;
                    if (m == s && ch == m) {
                        sb.append(h + ":" + m + ":" + s + "\n");
                    }
                }
            }
        }
        System.out.println(sb.toString());
    }

    /**
     * 计算三针重叠方法三,但该方法认为三颗针是匀速不停的在运转,与方法一和方法二的思路不同
     * 
     * 秒针60秒是360°,分针60*60=3600秒是360°,时针12*60*60=43200秒是360°,
     * 所以每秒钟秒针分针时针走的度数分别是6°,0.1°,1/120°。 设从0点0分0秒过了x秒(x<43200),
     * 则秒针走了[6x(mod)360]°{注:mod是取余},分针走了[x/10(mod)360]°, 时针走了x/120度。
     * 三针重叠就是要求在某一时刻,三针映射到时钟面上的角度相同
     */
    public static void method3() {
        for (int i = 0; i <= 24 * 60 * 60; i++) {
            if ((6 * i) % 360 == (0.1 * i) % 360) {
                if ((0.1 * i) % 360 == (1 / 120.0) * i % 360) {
                    System.out.println(i / 3600 + ":" + i % 3600 / 60 + ":" + i % 3600 % 60 / 60 + "\n");
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("------------------------ 《方法一》 -------------------------");
        method01();

        System.out.println("------------------------ 《方法二》 -------------------------");
        method02();

        System.out.println("------------------------ 《方法二》 -------------------------");
        method3();
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值