鱼C论坛

 找回密码
 立即注册
查看: 5299|回复: 24

题目43:找出所有具有异常子串整除性的pandigital数之和

[复制链接]
发表于 2015-5-16 22:29:13 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 永恒的蓝色梦想 于 2020-6-3 19:27 编辑
Sub-string divisibility

The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property.

Let BaiduShurufa_2015-5-16_22-21-32.png be the BaiduShurufa_2015-5-16_22-21-57.png digit, BaiduShurufa_2015-5-16_22-22-36.png be the BaiduShurufa_2015-5-16_22-22-53.png digit, and so on. In this way, we note the following:

BaiduShurufa_2015-5-16_22-21-0.png

Find the sum of all 0 to 9 pandigital numbers with this property.

题目:

1406357289 是一个 pandigital 数,因为它包含了 0 到 9 之间每个数字且只包含了一次。此外它还有一个有趣的子串整除性质。

BaiduShurufa_2015-5-16_22-21-32.png 表示其第一位数字, BaiduShurufa_2015-5-16_22-22-36.png 表示第二位,以此类推。这样我们可以得到:

BaiduShurufa_2015-5-16_22-27-50.png

求所有具有如上性质的 0 到 9 pandigital 数的和。


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-8-30 18:01:00 | 显示全部楼层
跑了10几分钟  
3个数。。。
1406357289
1430952867
1460357289
还没跑完,等下补充
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>
  4. #include <strstream>
  5. using namespace  std;
  6. void unsigned_to_hex(unsigned int value, std::string& hex_string)
  7. {
  8.         std::strstream buffer;
  9.         buffer.setf(std::ios::showbase);
  10.         buffer  << value;   
  11.         buffer >> hex_string;
  12. }


  13. //这个数是不是pandight数字
  14. bool isnumpandig(unsigned int n)       
  15. {
  16.        
  17.        
  18.         string str;
  19.         unsigned_to_hex(n,str);
  20.         sort(str.begin(),str.end());
  21.         int i = str.size();

  22.         for (int n=0;n<i-1;n++)
  23.         {
  24.                 if(str[n]==str[n+1])
  25.                         return false;
  26.         }
  27.         return true;
  28. }
  29. //获取一个int类型的位数
  30. int get(unsigned int n)
  31. {
  32.         if(n==0) return 1;
  33.         int m = 0;
  34.         while (n)
  35.         {
  36.                 n/=10;
  37.                 m++;
  38.         }
  39.         return m;
  40. }
  41. //获取一个数的第几位
  42. //从左边开始第几个
  43. unsigned int  getnum(unsigned int n,int m)
  44. {
  45.         int k = get(n)-m+1; //就是右边的k个
  46.         int z = 1;
  47.         while (n)
  48.         {
  49.                 if(z==k)
  50.                         return n%10;
  51.                 n/=10;

  52.                 z++;

  53.         }
  54. }
  55. int cal(unsigned int num,int a,int b,int c)
  56. {
  57.         string str;
  58.     unsigned_to_hex(num,str);
  59.         int len =str.size();

  60.        
  61.         return (getnum(num,a)*100)+(getnum(num,b)*10)+(getnum(num,c));
  62. }
  63. int main(void)
  64. {
  65.         //从0123456789开始
  66.         //std::cout<<cal(2802399493,2,3,4);
  67.         //2802399493
  68.         for (unsigned int n=1023456789;n<=9876543210;n+=1)
  69.         {
  70.                 //满足几个性质
  71.                 if(isnumpandig(n))
  72.                 {
  73.                         //好尴尬
  74.                         if(cal(n,2,3,4)%2==0)
  75.                                 if(cal(n,3,4,5)%3==0)
  76.                                         if(cal(n,4,5,6)%5==0)
  77.                                                 if(cal(n,5,6,7)%7==0)
  78.                                                         if(cal(n,6,7,8)%11==0)
  79.                                                                 if(cal(n,7,8,9)%13==0)
  80.                                                                         if(cal(n,8,9,10)%17==0)
  81.                                                                                 std::cout<<n<<endl;

  82.                        
  83.                 }
  84.         }
  85.         return 0;
  86. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-8-30 19:04:32 | 显示全部楼层
1406357289
1430952867
1460357289
4106357289
4130952867
4160357289
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-30 21:21:28 | 显示全部楼层
迷雾少年 发表于 2016-8-30 18:01
跑了10几分钟  
3个数。。。
1406357289

能答出欧拉计划这些题的人不多呀` 支持迷雾大神~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-30 21:34:21 | 显示全部楼层
拈花小仙 发表于 2016-8-30 21:21
能答出欧拉计划这些题的人不多呀` 支持迷雾大神~

觉得无聊,就试着做做了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-30 21:44:56 | 显示全部楼层
迷雾少年 发表于 2016-8-30 21:34
觉得无聊,就试着做做了

迷雾大神在无聊次,我们就又多一份参考文献啦~
你编程技术高,能不能写篇日常关于编程过程中的小技巧整理、和心得体会呢。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-30 21:57:57 | 显示全部楼层
拈花小仙 发表于 2016-8-30 21:44
迷雾大神在无聊次,我们就又多一份参考文献啦~
你编程技术高,能不能写篇日常关于编程过程中 ...

会的,谢谢小仙支持
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-5 22:22:38 | 显示全部楼层
迷雾少年 发表于 2016-8-30 19:04
1406357289
1430952867
1460357289

答案应该是对的,但是我换了一种算法,不要穷举所有数,不然效率太低。
我是生成pandigital,然后依次判断,27.3秒搞定。
  1. ['4130952867', '1430952867', '4160357289', '4106357289', '1460357289', '1406357289']
  2. [Finished in 27.3s]
复制代码
  1. def getPan(n):
  2.         if n == 2:
  3.                 return ['210','120','102','201','021','012']
  4.         if n>2:
  5.                 pan = getPan(n-1)
  6.                 length = len(pan[0])
  7.                 pannew = []
  8.                 for each in pan:
  9.                         pannew.append(str(n)+str(each))
  10.                         pannew.append(str(each)+str(n))
  11.                         for j in range(1,length):
  12.                                 pannew.append(str(each)[:j]+str(n)+str(each)[j:])
  13.                 return pannew

  14. def judge(plist):
  15.         prime = [2,3,5,7,11,13,17]
  16.         returnlist = []
  17.         for each in plist:
  18.                 if each[0] == '0':
  19.                         pass
  20.                 else:
  21.                         flag = 1
  22.                         for j in range(1,8):
  23.                                 if each[j] == '0':
  24.                                         if int(each[j+1:j+3]) % prime[j-1] != 0:
  25.                                                 flag = 0
  26.                                                 break
  27.                                 else:
  28.                                         if int(each[j:j+3]) % prime[j-1] != 0:
  29.                                                 flag = 0
  30.                                                 break
  31.                         if flag == 1:
  32.                                 returnlist.append(each)
  33.         return returnlist

  34. plist = getPan(9)
  35. plist = judge(plist)
  36. print (plist)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-8 12:09:38 | 显示全部楼层
  1. from itertools import permutations as per
  2. x = lambda l: (l[1]*100+l[2]*10+l[3]) % 2 == 0 and (l[2]*100+l[3]*10+l[4]) % 3 == 0 and (l[3]*100+l[4]*10+l[5]) % 5 == 0 and (l[4]*100+l[5]*10+l[6]) % 7 == 0 and (l[5]*100+l[6]*10+l[7]) % 11 == 0 and (l[6]*100+l[7]*10+l[8]) % 13 == 0 and (l[7]*100+l[8]*10+l[9]) % 17 == 0
  3. for i in per([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]):
  4.     if i[0] == 0:
  5.         continue
  6.     if x(i):
  7.         print(i)
复制代码

  1. (1, 4, 0, 6, 3, 5, 7, 2, 8, 9)
  2. (1, 4, 3, 0, 9, 5, 2, 8, 6, 7)
  3. (1, 4, 6, 0, 3, 5, 7, 2, 8, 9)
  4. (4, 1, 0, 6, 3, 5, 7, 2, 8, 9)
  5. (4, 1, 3, 0, 9, 5, 2, 8, 6, 7)
  6. (4, 1, 6, 0, 3, 5, 7, 2, 8, 9)
  7. 请按任意键继续. . .
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-15 22:52:25 | 显示全部楼层
本帖最后由 芒果加黄桃 于 2017-1-15 22:53 编辑
  1. # encoding:utf-8
  2. # 查找三角形单词个数
  3. from time import time
  4. from itertools import permutations
  5. def euler043():
  6.     l_temp = [v for v in permutations([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 10)]
  7.     l_primes = [2, 3, 5, 7, 11, 13, 17]
  8.     l_pans = []
  9.     l_result = []
  10.     for each in l_temp:
  11.         if each[0] == 0:
  12.             continue
  13.         if each[3] % 2 != 0:
  14.             continue
  15.         if each[5] not in (0, 5):
  16.             continue
  17.         s = ''
  18.         for i in list(each):
  19.             s += str(i)
  20.         l_pans.append(s)
  21.     for each in l_pans:
  22.         flag = True
  23.         for j in range(0, 7):
  24.             if not int(each[j + 1:j + 4]) % l_primes[j] == 0:
  25.                 flag = False
  26.                 break
  27.         if flag:
  28.             l_result.append(int(each))
  29.     print(l_result)
  30.       
  31. if __name__ == '__main__':
  32.     start = time()
  33.     euler043()
  34.     print('cost %.6f sec' % (time() - start))
复制代码

[1406357289, 1430952867, 1460357289, 4106357289, 4130952867, 4160357289]
cost 3.463459 sec
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-13 00:14:25 | 显示全部楼层
此代码使用matlab编程
Problem43所用时间为491.9989秒
Problem43的答案为16695334890
算是优化到尽头了,还是跑了8分钟。。matlab的确有劣势
  1. %% Problem43.m
  2. %最后编辑时间:2017-06-12 23:13 版本1.0
  3. %找出满足0—9的pandigital数的个数
  4. % Problem43所用时间为491.9989秒
  5. % Problem43的答案为16695334890
  6. function Output = Problem43()
  7. tic
  8. Output = 0;
  9. All = perms('0123456789');
  10. [M,~] = size(All);

  11. Prime  = [2 3 5 7 11 13 17];
  12. for ii = 1:M
  13.     Num = All(ii,:);
  14.     disp(Num)
  15.     Cut = zeros(1,7);
  16.     Judge = 1;
  17.     for jj = 1:7
  18.         Cut(jj) = str2double(Num(jj+1:jj+3));
  19.         if mod(Cut(jj),Prime(jj)) ~= 0
  20.             Judge = 0;
  21.             break
  22.         end
  23.     end
  24.    
  25.     if Judge == 1
  26.         Output = Output + str2double(Num);
  27.     end
  28.             
  29. end
  30. toc

  31. disp('此代码使用matlab编程')
  32. disp(['Problem43所用时间为',num2str(toc),'秒'])
  33. disp(['Problem43的答案为',num2str(Output)])
  34. end
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-8-17 18:35:21 | 显示全部楼层
渡风 发表于 2017-6-13 00:14
此代码使用matlab编程
Problem43所用时间为491.9989秒
Problem43的答案为16695334890

肯定还可以优化的,我用matlab写的代码,耗时是30多秒
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-17 18:45:13 | 显示全部楼层
本帖最后由 cq_xuke 于 2017-8-17 18:50 编辑
  1. import time
  2. s=time.clock()
  3. from itertools import permutations
  4. from functools import reduce
  5. primes=[2,3,5,7,11,13,17]
  6. count=0
  7. for pandigits in permutations([9,8,7,6,5,4,3,2,1,0]):
  8.     if pandigits[0]==0:
  9.         break
  10.     i=1
  11.     for p in primes:
  12.         pan=reduce(lambda x,y:x*10+y,pandigits[i:i+3])
  13.         i+=1
  14.         if pan % p != 0:
  15.             break
  16.     else:
  17.         count+=reduce(lambda x,y:x*10+y,pandigits)
  18. print(count)
  19. print('Runing time: {0}s'.format(round(time.clock()-s,3)))
复制代码

16695334890
Runing time: 5.251s
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-19 19:12:56 | 显示全部楼层
  1. from time import time
  2. from itertools import permutations
  3. start = time()

  4. def Euler43(i):
  5.     list_1 = ['0','1','2','3','4','5','6','7','8','9']
  6.     list_2 = []
  7.     str_1 = ''
  8.     for each in i:
  9.         if each in list_1:
  10.             list_1.remove(each)
  11.     for each in range(0,len(list_1)):
  12.          s = list_1[each]+"".join(i)
  13.          list_2.append(s[0:3])
  14.     return  list_2

  15. sum = 0
  16. s = permutations('1234567890',3)
  17. for i in s :
  18.       if int(''.join(i[:])) % 17==0:
  19.             for each in Euler43(i):
  20.                 if int(each) %13 ==0:
  21.                     for b in Euler43(each[0]+''.join(i)):
  22.                         if int(b)%11==0:
  23.                            for c in Euler43(b[0]+each[0]+"".join(i)):
  24.                                if int(c)%7==0:
  25.                                    for d in Euler43(c[0]+b[0]+each[0]+"".join(i)):
  26.                                         if int(d)%5 ==0:
  27.                                             for e in Euler43(d[0]+c[0]+b[0]+each[0]+"".join(i)):
  28.                                                 if int(e)%3 == 0:
  29.                                                     for f in Euler43(e[0]+d[0]+c[0]+b[0]+each[0]+"".join(i)):
  30.                                                         if int(f)%2 ==0:
  31.                                                             for g in Euler43(f[0]+e[0]+d[0]+c[0]+b[0]+each[0]+"".join(i)):
  32.                                                                 sum = sum+int(g[0]+f[0]+e[0]+d[0]+c[0]+b[0]+each[0]+"".join(i))
  33. print(sum)
  34. print("Time taken %.6f s" % (time() - start))
复制代码


16695334890
Time taken 0.002000 s
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-30 09:31:42 | 显示全部楼层
用的matlab
结果是:
     1     6     6     9     5     3     3     4     8     9     0

时间已过 0.127576 秒。
>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-30 13:31:28 | 显示全部楼层
'''
ps:利用生成0~9pandigital 和 生成器相结合可以有效缩减时间

answer:
1406357289
1430952867
1460357289
4106357289
4130952867
4160357289
'''


def produce_9_pandigital():
        list2=[]
        for d0 in range(1,10):
                for d1 in range(10):
                        if d1 != d0:
                                for d2 in range(10):
                                        if d2 not in [d0,d1]:
                                                for d3 in range(10):
                                                        if d3 not in [d0,d1,d2]:
                                                                for d4 in range(10):
                                                                        if d4 not in [d0,d1,d2,d3]:
                                                                                for d5 in range(10):
                                                                                        if d5 not in [d0,d1,d2,d3,d4]:
                                                                                                for d6 in range(10):
                                                                                                        if d6 not in [d0,d1,d2,d3,d4,d5]:
                                                                                                                for d7 in range(10):
                                                                                                                        if d7 not in [d0,d1,d2,d3,d4,d5,d6]:
                                                                                                                                for d8 in range(10):
                                                                                                                                        if d8 not in [d0,d1,d2,d3,d4,d5,d6,d7]:
                                                                                                                                                for d9 in range(10):
                                                                                                                                                        if d9 not in [d0,d1,d2,d3,d4,d5,d6,d7,d8]:
                                                                                                                                                                str_num=str(d0)+str(d1)+str(d2)+str(d3)+str(d4)+str(d5)+str(d6)+str(d7)+str(d8)+str(d9)
                                                                                                                                                                yield int(str_num)


for each in produce_9_pandigital():
                str_i=str(each)
                d_1=1
                d_2=2
                d_3=3
                list1=[2,3,5,7,11,13,17]
                for x in range(7):
                        sum_d1d2d3=int(str_i[d_1])*100 + int(str_i[d_2])*10 + int(str_i[d_3])
                        if sum_d1d2d3 % list1[x] != 0:
                                break
                        d_1+=1
                        d_2+=1
                        d_3+=1
                else:
                        print(each)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-29 16:35:56 | 显示全部楼层

  1. def perm(n):
  2.     import itertools
  3.     for i in range(n):
  4.         if i == 1:
  5.             listTemp = [0]
  6.         else:
  7.             listTemp = []
  8.             for j in range(i+1):
  9.                 listTemp.append(j)
  10.     list1 = list(itertools.permutations(listTemp, len(listTemp)))
  11.     numList = []
  12.     for i in range(len(list1)):
  13.         numStr = ""
  14.         for j in range(len(list1[i])):
  15.             numStr += str(list1[i][j])
  16.         num = int(numStr)
  17.         numList.append(num)
  18.     return numList

  19. TempNumList = perm(10)
  20. allNumList = []
  21. for each in TempNumList:
  22.     if len(str(each)) == 10:
  23.         allNumList.append(each)

  24. def SubNumList(Num):
  25.     SubNumList = []
  26.     for i in range(1, 8):
  27.         SubNumStr = ""
  28.         for j in range(3):
  29.             SubNumStr += str(Num)[i + j]
  30.         SubNumList.append(int(SubNumStr))
  31.     return SubNumList

  32. divisorList = [2, 3, 5, 7, 11, 13, 17]
  33. finalNumList = []
  34. for each1 in allNumList:
  35.     TempList = SubNumList(each1)
  36.     for i in range(len(TempList)):
  37.         if TempList[i] % divisorList[i] != 0:
  38.             break
  39.     else:
  40.         finalNumList.append(each1)

  41. print(finalNumList)
复制代码

[1406357289, 1430952867, 1460357289, 4106357289, 4130952867, 4160357289]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-14 15:31:16 | 显示全部楼层
结果是:['1406357289', '1430952867', '1460357289', '4106357289', '4130952867', '4160357289']
用时:4.6644299 秒

  1. import itertools
  2. import time

  3. def get_result():
  4.     result = []
  5.     for each in itertools.permutations([str(i) for i in range(10)]):
  6.         target_list = [2, 3, 5, 7, 11, 13, 17]
  7.         mark = 1
  8.         for i in range(7):
  9.             if int(each[1+i] + each[2+i] + each[3+i]) % target_list[i]:
  10.                 mark = 0
  11.                 break
  12.         if mark:
  13.             result.append("".join(each))
  14.     return result

  15. print("结果是:{}\n用时:{} 秒".format(get_result(), time.process_time()))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-17 17:15:50 | 显示全部楼层
16695334890

Process returned 0 (0x0)   execution time : 0.241 s
Press any key to continue.
进行了一通优化……从0.33提到0.24
枚举全排列
  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. typedef long long ll;

  5. const int p[] = {0,2,3,5,7,11,13,17};//0占位
  6. int a[] = {1,0,2,3,4,5,6,7,8,9};

  7. ll parse(int l,int r){
  8.   ll res = 0;

  9.   for (;l < r;l++){
  10.     res *= 10;
  11.     res += a[l];
  12.   }
  13.   return res;
  14. }

  15. int main(){
  16.   ll ans = 0;

  17.   do{
  18.     bool flag = true;
  19.     if (a[3] & 1) continue;
  20.     if ( (a[2]+a[3]+a[4]) % 3) continue;
  21.     if (a[5] && a[5] != 5)  continue;
  22.     if (a[5] + a[7] != a[6] && a[5] + a[7] != a[6] + 11)  continue;

  23.     for (int i = 1;i <= 7;i++){
  24.       int t = parse(i,i+3);
  25.       if (t % p[i]) {flag = false; break;}
  26.     }
  27.     if (flag) ans += parse(0,10);

  28.   }while(next_permutation(a,a+10));

  29.   cout << ans << endl;
  30.   return 0;
  31. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-13 12:36:36 | 显示全部楼层
  1. from time import time

  2. def getPan(n):#从大神处copy
  3.         if n == 2:
  4.                 return ['210','120','102','201','021','012']
  5.         if n>2:
  6.                 pan = getPan(n-1)
  7.                 length = len(pan[0])
  8.                 pannew = []
  9.                 for each in pan:
  10.                         pannew.append(str(n)+str(each))
  11.                         pannew.append(str(each)+str(n))
  12.                         for j in range(1,length):
  13.                                 pannew.append(str(each)[:j]+str(n)+str(each)[j:])
  14.                 return pannew
  15. t = time()
  16. list1 = getPan(9)
  17. list2 = []
  18. for i in list1:
  19.         if int(i[1:4])%2==0:
  20.                 if int(i[2:5])%3==0:
  21.                         if int(i[3:6])%5==0:
  22.                                 if int(i[4:7])%7==0:
  23.                                         if int(i[5:8])%11==0:
  24.                                                 if int(i[6:9])%13==0:
  25.                                                         if int(i[7:10])%17==0:
  26.                                                                 list2.append(int(i))
  27.                
  28. print(list2, '和是:', sum(list2))
  29. print('cos:',time()-t)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-20 01:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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