49

请听第一道算法题:爱健身的小王

 4 years ago
source link: https://www.tuicool.com/articles/E3qQfyj
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

刚参加工作的小伙伴可能觉得算法没什么用处,会工程开发就行,会写业务就行。但是当你达到一定的水平以后,你会发现系统的瓶颈可能在于算法,一个好的算法和一个差的算法在系统性能上的表现有云泥之别。不止于此,学习和练习算法也能锻炼人的思维能力,不管你做什么事都会有潜移默化的影响。所以,总之一句话,让我们现在就开始学习算法吧!

今年实习生招聘差不多也接近尾声了,各大厂的笔试题目在网上都能找到。今天我们看一道美团的笔试题,比较容易。

题目如下图所示:

MJJV7zz.png!web

image.png

这种题目切忌一上来就暴力求解。首先要分析一下题目的规律。我们假设小王从正方形的左上角(记为原点)开始走起。

首先分析一下小王会在哪里停下来。小王从起点走n+1步后打了第一个标记,我们记为A点,再走n+1步又打一个标记,记为B点,以此类推。假设小王打了若干次标记后不是在A点停下来,比如是在B点停下来,那么往回退n+1步,小王上一次一定是在A点重复打了一个标记,这就有矛盾了,所以,小王一定是在A点停下来的。

这个结论一旦成立,说明小王在A点重复打标记之前的一次就是在原点打标记。我们记小王一共标记了m次,那么在原点打标记就是第m-1次打标记,而每打一次标记要走n+1步,所以到第m-1次打标记为止一共走了(n+1)(m-1)步,这(n+1)(m-1)步刚好等于周长的若干倍,即

(n+1)(m-1)=4n*k

从这个式子中可以看出,(n+1)(m-1)既是n+1的倍数,也是4n的倍数,又因为我们要找的m是让上式第一次成立的m,所以我们只要找出n+1和4n的最小公倍数,然后除以n+1即可得到答案。

所以m=[n+1, 4n] / (n+1) + 1

而最小公倍数[n+1, 4n] = (n+1)*4n / (n+1, 4n)

所以m = 4n / (n+1, 4n) + 1

到这里我们发现这道题的本质变成了求最大公约数问题(gcd)。最大公约数问题的代码网上到处都是。

最后附上golang版的代码:

package main

import (
  "fmt"
  "strconv"
  "bufio"
  "os"
  "strings"
)

func main() {
  var ts string
  var ns string
  fmt.Scanln(&ts)
  t, _ := strconv.Atoi(ts)
  
  inputReader := bufio.NewReader(os.Stdin)
  ns, _ = inputReader.ReadString('\n')
  ns = strings.Trim(ns, "\r\n")
  n_slice := strings.Split(ns, " ")
  for i := 0; i < t; i++ {
    n, _ := strconv.Atoi(n_slice[i])
    fmt.Println(4*n/gcd(n+1, 4*n)+1)
  }
}

func gcd(a, b int) int {
  if b == 0 {
    return a
  } else {
    return gcd(b, a%b)
  }
}

大家想看更详细的视频解答的话,可以上b站或者斗鱼等网站上搜“大雪菜”(这个up主是北大的大神级人物),能找到相关的视频。

欢迎关注博主个人微信公众号~~~

67ziuer.jpg!web

image


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK