• 车站建造问题


    有10^8个村庄排在一条公路上,依次编号为0~10^8-1,相邻村庄距离为1,其中有n个村庄居住着牛牛,居住着牛牛的村庄从小到大依次为a0~an-1,其中保证a0=0.
    现在需要建设车站,有两个要求必须被满足:
    1、每个有牛牛居住的村庄必须修建车站。
    2、相邻车站的距离必须为1或为某个质数。
    现给出n和a数组,求需要建设车站的最小数量。

    来源:牛客网

    注意:

    输入数据包含一个数n和一个长度为n的数组a,数组a的下标为0~n-1,保证a数组递增,且a0=0。
    输出一个整数,表示答案。
    1<=n<=1000,a数组中数值保证小于10^8
    

    示例 1:

    输入
    3,[0,7,11]
    
    输出
    4
    
    说明
    在0,7,8,11处建造车站,差值分别为7,1,3,符合要求
    

    解题:

    package nc86;
    
    import java.util.HashSet;
    
    /**
     * @author focksor
     */
    public class Solution {
        /*
          题目描述
          有10^8个村庄排在一条公路上,依次编号为0~10^8-1,相邻村庄距离为1,其中有n个村庄居住着牛牛,居住着牛牛的村庄从小到大依次为a0~an-1,其中保证a0=0.
          现在需要建设车站,有两个要求必须被满足:
          1、每个有牛牛居住的村庄必须修建车站。
          2、相邻车站的距离必须为1或为某个质数。
          现给出n和a数组,求需要建设车站的最小数量。
          原题链接:https://www.nowcoder.com/questionTerminal/9fededa1b63a41798e5d43344d7bf216
         */
    
        public static HashSet<Integer> primes = new HashSet<>();
        public static HashSet<Integer> noPrimes = new HashSet<>();
    
        static {
            primes.add(1);
        }
    
        /**
         * @param n 住着牛牛的村庄的个数
         * @param a 住着牛牛的村庄的位置,从小到大排序,其中a[0]=0
         * @return 需要建设车站的最小数量
         */
        public int work (int n, int[] a) {
            /*
              “哥德巴赫猜想”:任一大于2的偶数都可写成两个素数之和。还有,任一大于5的整数都可写成三个质数之和。
              设两个车站的距离为len,则:
               如果len为素数,则车站数量+1
               如果len为偶数,则车站数量+2
               如果len为奇数,令len=(len-2)+2,则
                如果len-2为质数,则len就是len-2和2这两个质数之和,车站数量+2
                如果len-2不是质数,则len-2为两个质数之和,则len为三个质数之和,车站数量+3
              最后,再加上位于0的车站,车站数量+1
             */
    
            int sum = 0;
            for (int i = 0; i < n; i++) {
                if (i == 0) {
                    sum += 1;
                } else {
                    int len = a[i] - a[i-1];
                    if (isPrime(len)) {
                        sum++;
                    } else {
                        if (len%2 == 0) {
                            sum += 2;
                        } else {
                            sum += isPrime(len-2) ? 2 : 3;
                        }
                    }
                }
            }
    
            return sum;
        }
    
        public boolean isPrime(int n) {
            if (primes.contains(n)) {
                return true;
            }
            if (noPrimes.contains(n)) {
                return true;
            }
            for (int i = 2; i <= Math.sqrt(n); i++) {
                if (n%i == 0) {
                    noPrimes.add(n);
                    return false;
                }
            }
    
            primes.add(n);
            return true;
        }
    }
    
    

    本地测试代码

    package nc86;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
     * @author focksor
     * @date 2020/6/29 10:34
     */
    public class SolutionTest {
        /*
          示例1
          输入
            3,[0,7,11]
          输出
            4
          说明
            在0,7,8,11处建造车站,差值分别为7,1,3,符合要求
    
          备注:
          输入数据包含一个数n和一个长度为n的数组a,数组a的下标为0~n-1,保证a数组递增,且a0=0。
          输出一个整数,表示答案。
          1<=n<=1000,a数组中数值保证小于10^8
         */
    
        @Test
        public void test1() {
            int[] a = {0, 7 , 11};
            check(4, 3, a);
        }
    
        public void check(int res, int n, int[] a) {
            Solution solution = new Solution();
            Assert.assertEquals(res, solution.work(n, a));
        }
    }
    
    

    提交结果

    运行时间:40ms
    占用内存:12104k
    
  • 相关阅读:
    2018.7.12训练赛 -K
    winter 2018 02 01 关于模运算的一道题
    debug(实验)
    problem-1003(恢复一下)
    hd acm1466
    hd acm2045
    hd acm 1297
    hd acm1005
    hd acm1425
    概率趣题:三个犯人
  • 原文地址:https://www.cnblogs.com/focksor/p/13207245.html
Copyright © 2020-2023  润新知