记录一道阿里内推笔试题(站在原点能看几个其他的点)

师姐内推实习,可惜没有好好准备,半小时都没有完成这道题目,实在有愧.事后诸葛亮,现记录一下题目和求解思路,由于没有case,所以不知对错,欢迎指正.

题目大约如下:所有的同学都站在坐标系上的整数点,由原点看每个点,有的点被视线挡住了,求(长度为N时)原点能看到多少点,如下图所示:比如N = 1时 输出3; N=2时 输出5; N=3时 输出9; N = 4时,输出13?我应该没有算错吧.

看到这道题,我首先想到的就是递归,f(2) = f(1)+ g(2)... f(n) = f(n-1) + g(n), g(n)是关于最外围能看到点的函数.

所有问题在于求g(n)这个函数.最外围能看到几个点呢?首先最外围总共有2*n + 1个点(笔试写成2*n -1了,没注意0也是点), 减去看不到的点就是能看到的点,看不到的点的数应该是N的约数, 那么问题变成求N的约数个数了了. 笔试时想到这个,可惜函数出错了,case还是没过.此时g(n) = 2*n + 1 - ( 2 * N(约数个数) -1)

下面记录一下python(研究生期间一直都是用的python,原谅我python是我最熟的,后面有机会会更新一下c++的代码)的算法,由于没有case给我验证,我也不知道有没有出错的地方,所以解题思路和代码仅供参考,欢迎指正.

"""
Created on Sun Mar 25 15:15:50 2018

@author: hjxu
"""
import numpy as np
def countDivisors(num): #计算有多少个约数,这应该是计算约数时间复杂度最低的吧
    cnt = 0
    sqrt = int(num ** 0.5)
    for x in range(1, sqrt + 1):
        if num % x == 0:
            cnt += 1
    return cnt * 2 - (sqrt ** 2 == num)

def count_num(n):
    if n == 1:
        return 3
    else:
        result = np.zeros((n + 1))# 建立一个n+1的数组,用来存放数字
        result[1] = 3 # 从1开始,便于理解
        for i in range (2,n+1): #循环递归
            result[i] = result[i-1] + 2 * i + 1  - ( 2 * countDivisors(i ) -1) 
        return  int(result[n]) 

n = input('')  
if (isinstance(n,int) and n > 0):           
    print count_num(n)
else:
    print 'error! place enter Integer greater than 0'


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值