zoukankan      html  css  js  c++  java
  • [Swift]美人征婚问题

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:为敢(WeiGanTechnologies)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10777313.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

           公元2019年4月1日,时值西方愚人节,互联网激流暗涌,网络大佬各领风骚。然而从Internet某个小角落,一个征婚热帖撩动了广大单身攻城狮、程序猿、码农的热血激情。而今暗流退下,且让我们重新回味,整理一番。

    如你,猜测这是新出炉的高智商诈骗剧本?或者认为是某某互联网HR大佬招兵买马的钓鱼问题?就像你在百度首页按下[F12],映入眼帘的招聘文字。但我们眼中只看到算法问题,微信号是我们是特别不关心的事情。这个征婚正文比较影响你的关注点,我现在马上提炼出具体的问题: 

    问题1:求乘积为[7140229933]的两个质数? 

    问题2:求乘积为[6541367***]的两个质数?

     

    问题1思路历程: 

    质数(prime number)定义:在大于1的自然数中,只能被自身或1整除的数即为质数。质数又称素数,质数有无限多个。 

    (1)、我们先用埃拉托色尼筛选法求出指定范围的质数集合。 

    埃拉托色尼筛选法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosthenes 274B.C.~194B.C.)提出的一种筛选法。 是针对自然数列中的自然数而实施的,用于求一定范围内的质数,它的容斥原理之完备性条件是p=H~。

    埃氏筛法步骤: 

    (a).先把1删除(1既不是质数也不是合数) 

    (b).读取队列中当前最小的数2,然后把2的倍数删去 

    (c).读取队列中当前最小的数3,然后把3的倍数删去 

    (d).读取队列中当前最小的数5,然后把5的倍数删去 

    (e).读取队列中当前最小的数7,然后把7的倍数删去 

    (f).如上所述直到需求的范围内所有的数均删除或读取

    注意:此处的队列并非数据结构队列,如需保留运算结果,处于存储空间的充分利用以及大量删除操作的实施,建议采用链表的数据结构。

    (2)、有了质数集合,两数之积这个问题是不是有一点眼熟呢? 

    正在美帝田纳西求学的大神级前辈Grandyang告诉我们:平生不识TwoSum,刷尽LeetCode也枉然。。。。。 

    因为7140229933是10位数,每个因数平均是5位。所以我们可以选择筛选出十万范围内的质数,只需一次通过哈希表,尝试求出这两个质数(理工女同学的微信号)。并且我们把求质数的范围作为一个参数,如果十万范围里面求不出结果,我们可以扩大筛选范围。

    Talk is cheap.Show me your code.多说无用,看我行动。 

     1 import Foundation
     2 class Solution {
     3     func findBeauty(_ number:Int, _ target: Int) -> String {
     4         var primes = Set(2...number)
     5         //埃拉托色尼筛选法
     6         (2...Int(sqrt(Double(number)))).forEach {
     7             let _ = primes.subtract(stride(from: 2*$0, through: number, by: $0))
     8         }
     9         //转换为Double
    10         let nums:[Double] = Array(primes).map{Double($0)}
    11         var table:[Double:Double] = [Double:Double]()
    12         for (firstIndex, num) in nums.enumerated() {
    13             let res: Double = Double(target) / Double(num)
    14             //可选链接
    15             if table[res] == nil
    16             {
    17                 table[num] = Double(firstIndex)
    18             }
    19             else
    20             {
    21                 //转换为Int
    22                 let res:Int = Int(res)
    23                 let num:Int = Int(num)
    24                 print(res)
    25                 print(num)
    26                 let str:String = res > num ? (String(num) + String(res)) : String(res) + String(num)
    27                 return "Lin" + str
    28             }
    29         }
    30         return String()
    31     }
    32 }

    点击:Playground测试

    1 //测试
    2 print(Solution().findBeauty(100000, 7140229933))
    3 //Print 85229
    4 //Print 83777
    5 //Print Lin8377785229

    注意:已经输出女同学的微信号。但是你搜索之后会发现,这只是个小号。认真看完第2问,文章末尾告诉你常用微信号。

    问题2思路历程:

    我们同样用埃拉托色尼筛选法求出指定范围的质数集合。积为10位数,每个因数平均是5位。所以我们筛选出十万范围内的质数尝试求出结果。我们把求质数的范围作为一个参数,如果十万范围里面求不出结果,我们可以扩大筛选范围。6541367***最后三位数未知。但是我们可以知道:

    最小值:6541367000

    最大值:6541367999

    遍历筛选的质数集合,满足三个条件:

    (a)、同时用最大值和最小值分别除以集合中遍历的元素,所得两个商为一个浮点数,浮点数落在连续的两个整数范围内。因为质数为奇数,所以我们取这两个整数中的奇数。取整的两个奇数判等。

    (b)、判等的奇数,也必在筛选的质数集合中。

    (c)、判等的奇数和遍历的质数之积,减去与1000求余所得结果为最小值。

    Talk is cheap.Show me your code.多说无用,看我行动。

     1 import Foundation
     2 class Solution {
     3     func findBeauty2(_ number:Int, _ target: Int) -> [Int] {
     4         var primes = Set(2...number)
     5         //埃拉托色尼筛选法
     6         (2...Int(sqrt(Double(number)))).forEach {
     7             let _ = primes.subtract(stride(from: 2*$0, through: number, by: $0))
     8         }
     9         let nums:[Int] = Array(primes).sorted()
    10         //最小值
    11         let minNum:Int = target * 1000
    12         //最大值
    13         let maxNum:Int = minNum + 999
    14         //遍历数组
    15         for i in 0..<nums.count - 1
    16         {
    17             let num1:Int = getOdd(maxNum,nums[i])
    18             let num2:Int = getOdd(minNum,nums[i])
    19             let num3:Int = num1 * nums[i]
    20             //质数必须是奇数
    21             if num1 == num2 && nums.contains(num1) && minNum == (num3 - num3 % 1000)
    22             {
    23                print(num3)
    24                return([nums[i],num1])
    25             }
    26         }
    27         return [-1,-1]
    28     }
    29     
    30     //质数必为奇数,获取奇数
    31     func getOdd(_ num1:Int,_ num2:Int) -> Int
    32     {
    33         let number:Int = Int(ceil(Double(num1) / Double(num2)))
    34         return number % 2 == 0 ? (number - 1) : number
    35     }
    36 }

    点击:Playground测试

    1 //测试
    2 print(Solution().findBeauty2(100000, 6541367))
    3 //Print 6541367489
    4 //Print [67049, 97561]

    但是我们还没拿到美人的微信大号呢!经过我夜观天象,掐指一算。获得美女学霸其人真正微信:(点击左上角菜单,扫一扫加博主微信。向博主咨询)

  • 相关阅读:
    Screen-后台运行
    Env:ctags和Taglist安装与配置
    Env:Cscope安装与配置
    Env:VIM配置
    Env:zsh和fish安装和使用
    UIWebView与JS的深度交互-b
    利用Multipeer Connectivity框架进行WiFi传输-b
    iOS上绘制自然的签名-b
    1行代码为每个Controller自定义“TabBar”-b
    视频边下边播--缓存播放数据流-b
  • 原文地址:https://www.cnblogs.com/strengthen/p/10777313.html
Copyright © 2011-2022 走看看