鱼C论坛

 找回密码
 立即注册
查看: 2725|回复: 22

[已解决]Python:每日一题 256

[复制链接]
发表于 2019-10-13 13:07:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天的题目:


给定正整数 n,找到能组成 n 的完全平方数(比如 1, 4, 9, 16, ...)。你需要让组成 n 的完全平方数的个数最少。

难度:★★★☆☆
注意:为了提高鱼油们的积极性,前 10 位答对的鱼油才有奖哦 ~

示例 1:

输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4
示例 2:

输入: n = 13
输出: 2
解释: 13 = 4 + 9


欢迎大家一起答题!
最佳答案
2019-10-14 06:50:15
  1. class SquareFactor:

  2.     def get_factor(self, number):
  3.         factor = 1
  4.         while number % 4 == 0:
  5.             number /= 4
  6.             factor *= 4

  7.         return int(number), factor

  8.     def get_maxSqrtRoot(self, number):
  9.         root = math.sqrt(number)
  10.         return int(root)

  11.     def num_squares(self, number):
  12.         if not number:
  13.             return 0

  14.         number, factor = self.get_factor(number)
  15.         queue = list()
  16.         queue.append([number, 0])
  17.         visited = [number == i for i in range(number + 1)]
  18.         
  19.         while any(queue):
  20.             num, step = queue.pop(0)

  21.             i = 1
  22.             remain = num - i*i
  23.             while remain >= 0:
  24.                 if not remain:
  25.                     return step + 1

  26.                 if not visited[remain]:
  27.                     queue.append([remain, step+1])
  28.                     visited[remain] = True

  29.                 i += 1
  30.                 remain = num - i*i            
  31.         

  32. if __name__ == '__main__':

  33.     sf = SquareFactor()
  34.     print(sf.num_squares(13))
复制代码

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-13 15:38:17 | 显示全部楼层
本帖最后由 MyWifeDF41 于 2019-10-13 15:43 编辑
  1. '''
  2. 把12分别拆成1、11;4、8;9、3;然后再拆11、8、3。
  3. 11最少是9 1 1,3 个数,因此12可拆成四个数;
  4. 8最少是4 4,12拆成三个数
  5. 3最少是1 1 1,12拆成四个数
  6. 因此输出3
  7. '''

  8. def numSqu(n):
  9.     list = [float('inf') for i in range(n+1)]       #生成一个长度为n的list,每个元素表示平方的个数,初始为正无穷
  10.     list[0] = 0                                
  11.     for i in range(n+1):                            #计算组成i的完全平方数最少的个数
  12.         j = 1
  13.         while j**2 <= i :
  14.             list[i] = min(list[i],1 + list[i-j**2]) #把i分解为j**2+1, list[j**2] == 1, 比较哪种方法最小
  15.             j += 1

  16.     return list[i]
复制代码


如果算个大点的数,我感觉内存会爆。。。

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-10-13 16:46:43 | 显示全部楼层
本帖最后由 danteer 于 2019-10-13 16:49 编辑
  1. def func1(n):
  2.     list1 = []
  3.     list2 = []
  4.     count = 0
  5.     for i in range(int(n**0.5) + 1):
  6.         list1.append(i)
  7.     for i in list1:
  8.         for j in list1:
  9.             for k in list1:
  10.                 list2.append([i**2,i**2 + j**2,i**2 + j**2 + k**2])            
  11.     for each in list2:
  12.         if each[0] == n:
  13.             count = 1
  14.             break
  15.     if count != 0:
  16.         return count
  17.     for each in list2:
  18.         if each[1] == n:
  19.             count = 2
  20.             break
  21.     if count != 0:
  22.         return count
  23.     for each in list2:
  24.         if each[2] == n:
  25.             count = 3
  26.             break
  27.     if count != 0:
  28.         return count
  29.     else:
  30.         count = 4
  31.         return count
复制代码

四平方和定理说明每个正整数均可表示为4个整数的平方和。它是费马多边形数定理和华林问题的特例。
大概因为这个定理的关系可以省点劲?
反正我知道我这个程序算一个大的数字肯定超时,但是就当抛砖引玉了。

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-13 22:08:42 | 显示全部楼层
def solution(n: int) -> int:
        mylist = [n]
        step = 0

        while True:
            step += 1
            tmp = set()
            while mylist:
                n = mylist.pop()
                for i in range(1, int(n**0.5)+1):
                    cha = n-i**2
                    if cha == 0:
                        return step
                    else:
                        tmp.add(cha)
            mylist = list(tmp)

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 06:50:15 | 显示全部楼层    本楼为最佳答案   
  1. class SquareFactor:

  2.     def get_factor(self, number):
  3.         factor = 1
  4.         while number % 4 == 0:
  5.             number /= 4
  6.             factor *= 4

  7.         return int(number), factor

  8.     def get_maxSqrtRoot(self, number):
  9.         root = math.sqrt(number)
  10.         return int(root)

  11.     def num_squares(self, number):
  12.         if not number:
  13.             return 0

  14.         number, factor = self.get_factor(number)
  15.         queue = list()
  16.         queue.append([number, 0])
  17.         visited = [number == i for i in range(number + 1)]
  18.         
  19.         while any(queue):
  20.             num, step = queue.pop(0)

  21.             i = 1
  22.             remain = num - i*i
  23.             while remain >= 0:
  24.                 if not remain:
  25.                     return step + 1

  26.                 if not visited[remain]:
  27.                     queue.append([remain, step+1])
  28.                     visited[remain] = True

  29.                 i += 1
  30.                 remain = num - i*i            
  31.         

  32. if __name__ == '__main__':

  33.     sf = SquareFactor()
  34.     print(sf.num_squares(13))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 11:04:13 | 显示全部楼层
本帖最后由 Hoiste 于 2019-10-14 11:35 编辑

刚学习Python的新手现在水平有限,只用自己现在知道的一些内容编写了组成任意n的最少完全平方数,解释部分以后有思路再试试吧。。。
n = input('请输入任意正整数:')
n = int(n)
while n <= 0:
    print('要求输入的是正整数哦!')
    n = input('请输入任意正整数:')
    n = int(n)
print('你输入的数字是:'+str(n))

i = 1
k = 0
rest = n
if i ** 2 == rest:
    k = k + 1
    print('组成n的完全平方数个数为:'+str(k))
else:
    while i ** 2 < rest:
        i = i + 1
        if i ** 2 > rest:
            rest = rest - (i - 1) ** 2
            k = k + 1
            i = 1
        if i ** 2 == rest:
            k = k + 1
            print('组成n的完全平方数个数为:'+str(k))
            break

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 11:26:52 | 显示全部楼层
本帖最后由 华博文 于 2019-10-14 18:19 编辑

最大数测试为:12345678901 , 出的还是挺快的,把#去掉有详细信息但是会慢很多~~
自己琢磨瞎写的,跟大佬们学习

  1. import math

  2. zong = list()


  3. def yun(guess , sq_guess , zhan):
  4.     re_guess = guess - (sq_guess * sq_guess)
  5.    # print(re_guess)
  6.     bian = str(math.sqrt(re_guess))
  7.     if int(bian[bian.find(".") + 1 : ]) != 0:
  8.         zhan.append(sq_guess * sq_guess)
  9.         yun(re_guess , int(float(bian)) , zhan)
  10.         return zhan
  11.     else:
  12.         zhan.append(sq_guess * sq_guess)
  13.         if re_guess != 0:
  14.             zhan.append(re_guess)
  15.         return zhan

  16.    
  17. def eson(guess , zong = zong):
  18.     sq_guess = int(math.sqrt(guess))
  19.     for each in range(sq_guess , 0 , -1):
  20.         zhan = list()
  21.         zhan = yun(guess , each , zhan)
  22.         zong.append(zhan)
  23.     return zong

  24. if __name__ == "__main__":
  25.     text = ""
  26.     try:
  27.         wen = input("请输入一个整数,求出组成它的完全平方组:")
  28.         if int(wen) != 0:
  29.             #请从此处开始测试,看更详细的答案请把下列【#】全部去掉~~
  30.             lis = [each for each in eson(int(wen) , zong)]
  31.             lis_len = [len(each) for each in lis]
  32.             #dex = [lis[each] for each in range(len(lis)) if len(lis[each]) == min(lis_len)]
  33.             print("结果为:{}".format(min(lis_len)) , end="")
  34.             #print("\n详细:" , end="")
  35.             #for fir in dex:
  36.                 #text += "\n      "
  37.                 #for sec in range(len(fir) - 1):
  38.                     #text += str(fir[sec]) + " + "
  39.                 #text += str(fir[-1])
  40.             #print(text)
  41.         else:
  42.             print("结果为:0")
  43.     except (ValueError , TypeError):
  44.         print("您输入的数值不可运算~~")
  45.    
  46.         
  47.         
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 14:01:23 | 显示全部楼层
本帖最后由 Garou 于 2019-10-14 16:04 编辑

!!!###注意:该段代码是用python27实现的###!!!
最近在通过python27学习一些东西,wxpython;
这样会是最短的吗,抱有疑惑不敢肯定。。。


  1. inputValue = int(input("请输入一个正整数: "))

  2. tempList = []
  3. value = None

  4. tempValue = inputValue

  5. if value == None:
  6.     # 开方并保留一位小数,再将其转化为int
  7.     value = int(round(tempValue ** 0.5, 1))
  8.     tempValue = tempValue - value ** 2
  9.     tempList.append(value)
  10.     while True:
  11.         if tempValue >= 4:
  12.             value = int(round(tempValue ** 0.5, 1))
  13.             tempValue = tempValue - value ** 2
  14.             tempList.append(value)
  15.             print value
  16.             print tempValue
  17.         elif tempValue >= 1:
  18.             a_list = [1] * tempValue
  19.             tempList += a_list
  20.             tempValue = None
  21.         else:
  22.             break


  23. print tempList

  24. list  = []
  25. for ii in tempList:
  26.     aa = ii**2
  27.     list.append(aa)
  28. print list

  29. print len(list)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 15:56:09 | 显示全部楼层
我这个数大了也爆炸...
而且自己有的地方也理解
  1. list_sum=[]
  2. dict_res={}
  3. temp=input('请输入一个整数:')
  4. def x(each_1,list_n,n,temp):#递归求值
  5.     global list_sum
  6.    
  7.     for each_2 in range(0,n+1):
  8.         if each_1 + each_2 == n:
  9.             if each_2==0:
  10.                 list_sum.append(each_1)
  11.                 count=len(list_sum)
  12.                
  13.                 if sum(list_sum)==temp:#这里递归到最后有个值是1,不知道怎么去掉,所以加了个if,求指点
  14.                     dict_res[count]=list_sum
  15.                 list_sum=[]
  16.                 continue
  17.          
  18.             elif each_2 in list_n:
  19.                 list_sum.append(each_2)
  20.                 count=len(list_sum)
  21.                
  22.                 if sum(list_sum)==temp:
  23.                     dict_res[count]=list_sum
  24.                 list_sum=[]
  25.                 continue
  26.             
  27.             else:
  28.                 list_sum.append(each_1)
  29.                 n-=each_1
  30.                 for each_1 in list_n:
  31.                     return x(each_1,list_n,n,temp)

  32. def sumn(list_n,n,temp):
  33.     global count
  34.     for each_1 in list_n:
  35.         x(each_1,list_n,n,temp)
  36.             

  37. def fun(temp):
  38.     global dict_res
  39.     n=temp+1
  40.     list_n=[]
  41.     num=int(n**0.5)
  42.     list_x=[x for x in range(1,num+1)]
  43.    
  44.     for each in list_x:
  45.         list_n.append(each**2)
  46.     sumn(list_n,n,temp)

  47.     #准备输出结果及解释
  48.     explain=''
  49.     i=1
  50.     for each in dict_res[min(dict_res)]:
  51.         if i<len(dict_res[min(dict_res)]):
  52.             explain=explain+str(each)+'+'
  53.             i+=1
  54.         else:
  55.             explain=explain+str(each)
  56.             
  57.     explain=str(sum(dict_res[min(dict_res)]))+'='+explain
  58.    
  59.     print('输出:%d\n解释:%s'%(min(dict_res),explain))

  60.     dict_res={}#初始化,为下轮做准备

  61. fun(int(temp))
复制代码
不了..
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 16:07:59 | 显示全部楼层
本帖最后由 __mrsq__ 于 2019-10-14 16:12 编辑
  1. def fun256(num):
  2.         rt = int(num**0.5)
  3.         set0 = {num}
  4.         set1 = {n**2 for n in range(1,rt+1)}
  5.         set2 = {num -n**2 for n in range(1,rt+1)}
  6.         set3 = {num - m**2 - n**2 for n in range(1,rt+1) for m in range(1,rt+1)}
  7.         set4 = {num - m**2 - n**2 -l**2 for n in range(1,rt+1) for m in range(1,rt+1) for l in range(1,rt+1)}
  8.         if not(set1.isdisjoint(set0)):
  9.                 return 1
  10.         elif not(set1.isdisjoint(set2)):
  11.                 return 2
  12.         elif not(set1.isdisjoint(set3)):
  13.                 return 3
  14.         else:
  15.                 return 4
复制代码


emm也利用了四平和定理,总感觉有点作弊的嫌疑

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:19:32 | 显示全部楼层
MyWifeDF41 发表于 2019-10-13 15:38
如果算个大点的数,我感觉内存会爆。。。

输入 4128 超时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:22:30 | 显示全部楼层
danteer 发表于 2019-10-13 16:46
四平方和定理说明每个正整数均可表示为4个整数的平方和。它是费马多边形数定理和华林问题的特例。
大概 ...

输入 437 超时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:23:10 | 显示全部楼层
战场原 发表于 2019-10-13 22:08
def solution(n: int) -> int:
        mylist = [n]
        step = 0

恭喜通过!

执行用时:612 ms
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:24:59 | 显示全部楼层

恭喜通过!

执行用时:216 ms
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:27:55 | 显示全部楼层
Hoiste 发表于 2019-10-14 11:04
刚学习Python的新手现在水平有限,只用自己现在知道的一些内容编写了组成任意n的最少完全平方数,解释部分 ...

虽然解答错误,但是代码比较规范!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:30:23 | 显示全部楼层
华博文 发表于 2019-10-14 11:26
最大数测试为:12345678901 , 出的还是挺快的,把#去掉有详细信息但是会慢很多~~
自己琢磨瞎 ...

解答错误

输入:48
输出:4
预期结果:3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:33:02 | 显示全部楼层
Garou 发表于 2019-10-14 14:01
!!!###注意:该段代码是用python27实现的###!!!
最近在通过python27学习一些东西,wxpython;
这样 ...

输入 12 出错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:36:14 | 显示全部楼层
756437832 发表于 2019-10-14 15:56
我这个数大了也爆炸...
而且自己有的地方也理解不了..

解答错误。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-14 20:37:07 | 显示全部楼层
__mrsq__ 发表于 2019-10-14 16:07
emm也利用了四平和定理,总感觉有点作弊的嫌疑

输入 7691 超时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-15 13:12:05 | 显示全部楼层

看不太懂,可以解释一下吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 06:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表