特殊的pandigital数(有人译数独数)

来源:互联网 发布:php交友网站源码 编辑:程序博客网 时间:2024/04/30 06:39

编程时遇到了一个问题,strtol返回值上限居然是2^32-1,用他的返回值求和根本做无用功,我就重新写了个strtol_adv函数(返回值为long long,上限2^64-1)。

/*

1406357289 是由 0 ~ 9 的数字所组成的 pandigital 数

如果 d1 表示第 1 个数字,d2 表示第 2 个数字,以此类推,发现有下列的性质:

  • d2d3d4=406 可以被 2 整除
  • d3d4d5=063 可以被 3 整除
  • d4d5d6=635 可以被 5 整除
  • d5d6d7=357 可以被 7 整除
  • d6d7d8=572 可以被 11 整除
  • d7d8d9=728 可以被 13 整除
  • d8d9d10=289 可以被 17 整除

请问由 0 ~ 9 的数字所组成的 pandigital 数,都符合上列性质的所有的数的总和是多少?

注:1406357289 是最小的一个,还有 5 个。

1406357289
1430952867
1460357289
4106357289
4130952867
4160357289
sum value 16695334890

*/


//


// ceshiyongde.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <iostream>
using namespace std;


long long strtol_adv(char * str, int len)
{
long long num=0;
int i;


for(i=0; i<=len-1; i++)
{
num=num*10+str[i]-'0';
}


return num;
}





bool IsPassChongFu(int *a, int sub, int shiTanZhi)//通过重复验证
{
int i;
for(i=0; i<sub; i++)
{
if(a[i] == shiTanZhi)
return false;
}


return true;
}


bool IsPassChuSuShuYanZheng(int *a, int sub, int shiTanZhi)//通过除素数验证
{
int num;
/*
1406357289是一个很有趣的数,首先他是由0~9这10个数字组成,而且每个数字只用了一次。
我们把1406357289的第一位称作d1,第二位称作d2……,最后一位称作d10。你会发现以下规律
d2d3d4=406 可以被 2 整除
d3d4d5=063 可以被 3 整除
d4d5d6=635 可以被 5 整除
d5d6d7=357 可以被 7 整除
d6d7d8=572 可以被 11 整除
d7d8d9=728 可以被 13 整除
d8d9d10=289 可以被 17 整除
2,3,5,7,11,13,17恰好是连续的质数
*/


if(sub == 10-1)//10
{
num=a[7]*100+a[8]*10+shiTanZhi;
if( (num % 17)  ==  0)
{
return true;
}
else
return false;
}


if(sub == 9-1)//
{
num=a[6]*100+a[7]*10+shiTanZhi;
if((num%13) == 0)
{
return true;
}
else
return false;
}


if(sub == 8-1)//
{
num=a[5]*100+a[6]*10+shiTanZhi;
if((num%11)  == 0)
{
return true;
}
else
return false;
}


if(sub == 7-1)//
{
num=a[4]*100+a[5]*10+shiTanZhi;
if((num%7)  == 0)
{
return true;
}
else
return false;
}


if(sub == 6-1)//
{
num=a[3]*100+a[4]*10+shiTanZhi;
if((num%5)  == 0)
{
return true;
}
else
return false;
}


if(sub == 5-1)//
{
num=a[2]*100+a[3]*10+shiTanZhi;
if((num%3)  == 0)
{
return true;
}
else
return false;
}


if(sub == 4-1)//
{
num=a[5]*100+a[6]*10+shiTanZhi;
if((num%2)  == 0)
{
return true;
}
else
return false;
}


return false;




}


void HuiSuoQiu()
{
char str[11];
char *stop;


long long sum=0,temp;
int a[10],i,j,k,t;
int sub,shiTanZhi;
int const MaxSub=9;
int const MaxShiTanZhi=9;


str[10]='\0';
a[0]=1;
sub=1;
shiTanZhi=0;
while(true)
{
if(sub<0)
break;


if(sub> MaxSub)//生成可行解
{

for(i=0; i<MaxSub+1; i++)
{
cout<<a[i];
str[i]=a[i]+'0';
}
cout<<endl;


temp=strtol_adv(str, strlen(str));//temp=strtol(str,&stop, 10);
sum+=temp;
//////////////////
sub--;
shiTanZhi=a[sub]+1;
}


if(shiTanZhi > MaxShiTanZhi)
{
sub--;
shiTanZhi=a[sub]+1;
}
else
{
//if(a[0]==1  &&  a[1]==4  && a[2]==0)//if(a[0]==1  &&  a[1]==4  && a[2]==0  && a[3]==6)//1406357289
// t=0;
if( IsPassChongFu(a, sub, shiTanZhi)  )
{
if(sub>=3)
{
if( IsPassChuSuShuYanZheng(a, sub, shiTanZhi) )
{
a[sub]=shiTanZhi;
sub++;
shiTanZhi=0;
}
else
shiTanZhi++;
}
else
{
a[sub]=shiTanZhi;
sub++;
shiTanZhi=0;
}
}
else
{
shiTanZhi++;
}
}
}




cout<<"sum value "<<sum<<endl;
}


int _tmain(int argc, _TCHAR* argv[])



/*
1406357289是一个很有趣的数,首先他是由0~9这10个数字组成,而且每个数字只用了一次。
我们把1406357289的第一位称作d1,第二位称作d2……,最后一位称作d10。你会发现以下规律
d2d3d4=406 可以被 2 整除
d3d4d5=063 可以被 3 整除
d4d5d6=635 可以被 5 整除
d5d6d7=357 可以被 7 整除
d6d7d8=572 可以被 11 整除
d7d8d9=728 可以被 13 整除
d8d9d10=289 可以被 17 整除
2,3,5,7,11,13,17恰好是连续的质数
请问用0~9这10个数字可以组成多少个像1406357289这样的数呢?(每个数字只能使用一次)
请输出所有可能的数之和!
*/


    HuiSuoQiu();
//cout<<cntSuShu<<endl;


getchar(); 
return 0;
}