程序员的算法趣题Q12: 平方根数字

目录

1. 问题描述

2. 解题分析

3. 代码及测试


1. 问题描述

        求在计算平方根的时候,最早让0~9的数字全部出现的最小整数。注意这里只求平方根为正数的情况,并且请分别求包含整数部分的情况和只看小数部分的情况。

例)2的平方根 1.414213562373095048...0~9全部出现需要19位)

2. 解题分析

        这道题目比较含糊。

        其实是找平方根(含整数部分或不含整数部分的)前十位数字正好让 0~9 的数字全部出现(且不重复)的最小整数即构成0~9的一个排列(permutation)。

        关键在于题目要求既要求“最早”又要求“最小”。

        假定按自然数从小到大遍历,只有找到了一个平方根前十位数字正好让 0~9 的数字全部出现的数,你才能确信找到了满足题目条件的最小整数。

        在没有找到满足“平方根前十位数字正好让 0~9 的数字全部出现”的数之前,你无法确定后面是不是存在满足“平方根前十位数字正好让 0~9 的数字全部出现”的数,所以你只能继续找下去。

        所幸,满足“平方根前十位数字正好让 0~9 的数字全部出现”的数是存在的。

         代码中用以下判断前十个字符是否满足题设条件:

len(set(list(first10))) == 10

        这是因为set会自动删除重复元素,因此如果set的长度是10而其可能的元素又只能是0~9的话,那就必然满足条件。

3. 代码及测试

# -*- coding: utf-8 -*-
"""
Created on Sat Sep  4 08:51:51 2021

@author: chenxy
"""

import sys
import time
import datetime
import math
# import random
from   typing import List
# from   queue import Queue
# from   collections import deque

class Solution:
    def squareRoot1(self, sel:int) -> tuple:
        """
        Find the first interger, for which, either the first 10 digits of its square root, 
        or the first 10 digits of the decimal part of its square root, 
        includes all of 0~9.
        
        sel:  0--including integer part; 1: not including integer part
        ret: 
        """                
        i = 1
        while(1):
            i_sqrt = math.sqrt(i)
            i_sqrt_str = str(i_sqrt)

            # Find the position of decimal point
            for k in range(len(i_sqrt_str)):
                if i_sqrt_str[k] == '.':
                    break            
                
            if sel == 0:
                first10 = i_sqrt_str[0:k] + i_sqrt_str[k+1:11]
            else:
                first10 = i_sqrt_str[k+1:k+11]
                # print(first10,list(first10),set(list(first10)))
            
            if len(set(list(first10))) == 10:
                return i, i_sqrt
            
            i = i+1

    def squareRoot2(self) -> tuple:
        '''
        Find the first interger, for which, the first 10 digits of the decimal part of its square root, 
        includes all of 0~9.
        
        ret: 
        '''        
        num=1
        str_num='1.000000000000000'
        while len(set(list(str_num.split('.')[1][:10])))!=10:
        	num+=1
        	str_num=str(num**0.5)
        return num, num**0.5
                    
if __name__ == '__main__':        
            
    sln    = Solution()            
    
    tStart = time.time()
    num1,num1_sqrt = sln.squareRoot1(0) # including integer part
    num2,num2_sqrt = sln.squareRoot1(1) # Only considering fractional part
    tCost  = time.time() - tStart
    print('num1={0}, num1_sqrt={1:.10f}, tCost = {2:6.3f}(sec)'.format(num1,num1_sqrt,tCost))    
    print('num2={0}, num2_sqrt={1:.10f}, tCost = {2:6.3f}(sec)'.format(num2,num2_sqrt,tCost))    

    tStart = time.time()
    num3,num3_sqrt = sln.squareRoot2() # Only considering fractional part    
    tCost  = time.time() - tStart
    print('num3={0}, num3_sqrt={1:.10f}, tCost = {2:6.3f}(sec)'.format(num3,num3_sqrt,tCost))      

运行结果:

        num1=1362, num1_sqrt=36.9052841745, tCost =  0.003(sec)
        num2=143, num2_sqrt=11.9582607431, tCost =  0.003(sec)
        num3=143, num3_sqrt=11.9582607431, tCost =  0.000(sec)

[2021-09-05]

        Bijfah提示了利用字符串方法split()的更间接的代码,作为squareRoot2()追加到以上代码中了。善用python内置函数确实能让代码和运行效率都有脱胎换骨的效果。谢谢Bijfah的指点!但是squareRoot2()目前只能对付只考虑小数部分的情况,要对付含整数部分的情况的话还需要略修改造一下。

        上一篇:Q11: 斐波那契数列

        下一篇:Q13: 满足字母算式的解法

        本系列总目录参见:程序员的算法趣题:详细分析和Python全解

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值