5 回溯法Word格式.docx
- 文档编号:21093220
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:66
- 大小:40.37KB
5 回溯法Word格式.docx
《5 回溯法Word格式.docx》由会员分享,可在线阅读,更多相关《5 回溯法Word格式.docx(66页珍藏版)》请在冰豆网上搜索。
{
flag=1;
for(i=1;
i<
k;
i++)
if(a[k]==a[i])
flag=0;
break;
}
if(flag&
&
k==n)
for(j=1;
j<
=n;
j++)
a[j]);
\n"
if(k<
n&
flag){
k++;
a[k]=1;
continue;
while(a[k]==n&
k>
1){k--;
}
if(a[k]==n&
k==1)
else
a[k]++;
C++程序2、排列的算法差不多,为了不重复,加了一个条件,也就是递增数列
输入N,M:
%d%d"
n,&
m);
if(a[k]==a[i]||a[k]<
a[i])//a[k]<
a[i]条件为了限制递增
k==m)
=m;
flag)
C++程序3
#include<
string.h>
voidmain(){
intn,i=1;
请输入N值=?
"
inta[30]={0};
//C语言中完成数组定义并初始化不能用变量N,只能用具体数字,这儿采用比较大的30
while(i<
=n)
if(i==n){
for(intj=1;
n;
j++)printf("
%d"
printf("
%d\n"
a[n]);
//输出一组解
}
if(i<
n){i++;
a[i]=1;
continue;
while(a[i]==n&
i>
1)i--;
//向前回溯
if(a[i]==n&
i==1)break;
//结束
elsea[i]=a[i]+1;
}
JAVA程序
用回溯法求任意1到N个数字的全排列。
自动生成a[i]值(1到N间各1个数字),再全排列,如同N重循环中各下标的变化。
(类似于多重循环的穷举法,比多重循环的穷举法慢。
但程序有较通用的特性。
)
importjava.lang.Math;
importjava.util.*;
publicclassaa1
publicstaticvoidmain(String[]args)
System.out.println("
请输入位数"
Scannerscan1=newScanner(System.in);
intn=scan1.nextInt();
inti=1;
inta[]=newint[n+1];
if(i==n){
j++)System.out.print(a[j]);
System.out.println(a[n]);
}//其下一位回复为1
//程序运行全部结束
//向前回溯,前一位数字加1
2、求解21位水仙花数
程序1:
(用时6300毫秒)
importjava.math.BigInteger;
importjava.util.Arrays;
importjava.util.HashSet;
importjava.util.Hashtable;
publicclassTest{
publicstaticvoidmain(String[]args){
longxxx=System.currentTimeMillis();
//记录开始进入时的时间
Testtest=newTest(21);
//修改本数字可以求任何一位水仙花数
HashSet<
BigInteger>
set=newHashSet<
();
ints=test.MAX.divide(test.p(9)).intValue();
//System.out.println("
s="
+s);
for(inti=0;
i<
=s;
i++){
BigIntegertemp=test.solve(i);
if(temp!
=null)set.add(temp);
//加入一个满足要求的解
BigInteger[]result=newBigInteger[set.size()];
result="
+result);
set.toArray(result);
Arrays.sort(result);
for(BigIntegerbi:
result){
bi="
+bi);
xxx=System.currentTimeMillis()-xxx;
//记录退出时的时间
用时:
+xxx+"
毫秒"
//显示程序运行时间
publicTest(intsize){
this.size=size;
ints=size<
10?
10:
size;
ht.put("
n_"
+i,newBigInteger(String.valueOf(i)));
=10;
p_"
+i,newBigInteger(String.valueOf(i)).pow(size));
MIN=n(10).pow(size-1);
MAX=n(10).pow(size).subtract(n
(1));
privateintsize;
privateint[]array=newint[10];
privateint[]sumArray=newint[10];
privateBigInteger[]totalSum=newBigInteger[10];
privateintindex=0;
privateBigIntegerZERO=BigInteger.ZERO;
privateBigIntegerMIN;
privateBigIntegerMAX;
privateHashtable<
String,BigInteger>
ht=newHashtable<
privateBigIntegern(inti){
//System.out.println("
n_+i="
+i);
returnht.get("
+i);
privateBigIntegerp(inti){
p_+i="
privatebooleancheckPersentArray(){
BigIntegerminVal=totalSum[index];
BigIntegermaxVal=totalSum[index].add(p(9-index).multiply(
n(size-sumArray[index])));
if(minVpareTo(MAX)>
0){
returnfalse;
if(maxVpareTo(MIN)<
StringminStr=minVpareTo(MIN)>
0?
minVal.toString():
MIN
.toString();
StringmaxStr=maxVpareTo(MAX)<
maxVal.toString():
MAX
int[]sameCountArray=newint[10];
charc;
if((c=minStr.charAt(i))==maxStr.charAt(i)){
sameCountArray[c-'
0'
]=sameCountArray[c-'
]+1;
}else{
=index;
if(array[i]<
sameCountArray[9-i]){
if(sumArray[index]==size){
StringsumStr=totalSum[index].toString();
BigIntegersum=ZERO;
sumStr.length();
sum=sum.add(p(sumStr.charAt(i)-'
));
returnpareTo(totalSum[index])==0;
returntrue;
privatevoidsetValue(intnum){
array[index]=num;
if(index==0){
sumArray[index]=num;
totalSum[index]=p(9-index).multiply(n(num));
n(num)totalSum[index]="
+totalSum[index]+"
index="
+index);
//try{Thread.sleep(1000);
}catch(InterruptedExceptionex){}//暂停6秒
sumArray[index]=sumArray[index-1]+num;
totalSum[index]=totalSum[index-1].add(p(9-index).multiply(n(num)));
elsetotalSum[index]="
+totalSum[index]);
privatebooleanback(){
if(array[index]==0){
while(array[index]==0){
if(index>
index--;
setValue(array[index]-1);
elsefalse="
+false);
}catch(InterruptedExceptionex){}//暂停3秒
privateBigIntegersolve(intstartValue){
index=0;
setValue(startValue);
while(true){
if(checkPersentArray()){
if(sumArray[index]==size){//如果数组之和针对全数组,满足条件,返回一个解
returntotalSum[index];
if(index!
=9){
index++;
setValue(size-sumArray[index-1]);
if(back()){
returnnull;
程序2:
(用时9828毫秒)穷举法
importjava.lang.System;
importjava.io.*;
publicclassaa18{
staticinta[]={0,1,2097152,353203,6511104,8203125,377856,3284007,4775808,2359209};
staticintb[]={0,0,0,1046,439804,7683715,3695064,4586408,7203685,8913151};
staticintc[]={0,0,0,0,0,4,219,5585,92233,1094189};
staticintd[]={0,0,0};
staticintg[]=newint[10];
//staticinti=0,j=0,k=0,sum=0;
staticintx=0,y=0,z=0;
staticintx1=0,y1=0,z1=0;
longxxx=System.currentTimeMillis();
//以下i0表示0的个数,最多20个0,i1表示1的个数,最多21个1等
for(inti0=0;
i0<
=20;
i0++){
for(inti1=0;
i1<
=21;
i1++){if(i0+i1>
21)continue;
for(inti2=0;
i2<
i2++){if(i0+i1+i2>
for(inti3=0;
i3<
i3++){if(i0+i1+i2+i3>
//如果数字的个数超过21或不到20个,退出本循环continue
for(inti4=0;
i4<
i4++){if(i0+i1+i2+i3+i4>
for(inti5=0;
i5<
i5++){if(i0+i1+i2+i3+i4+i5>
for(inti6=0;
i6<
i6++){if(i0+i1+i2+i3+i4+i5+i6>
for(inti7=0;
i7<
i7++){if(i0+i1+i2+i3+i4+i5+i6+i7>
for(inti8=0;
i8<
i8++){if(i0+i1+i2+i3+i4+i5+i6+i7+i8>
for(inti9=0;
i9<
i9++){if(i0+i1+i2+i3+i4+i5+i6+i7+i8+i9!
=21)continue;
//以下求每个数字的21次方之和
//System.out.println(i0+"
+i1+"
+i2+"
+i3+"
+i4+"
+i5+"
+i6+"
+i7+"
+i8+"
+i9);
d[0]=a[1]*i1+a[2]*i2+a[3]*i3+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9;
//低7位之和
d[0]="
+d[0]);
d[1]=d[0]/10000000;
//向中7位的进位
d[0]=d[0]%10000000;
d[1]=d[1]+b[3]*i3+b[4]*i4+b[5]*i5+b[6]*i6+b[7]*i7+b[8]*i8+b[9]*i9;
//中7位之和
d[1]="
+d[1]);
d[2]=d[1]/10000000;
//向高7位的进位
d[1]=d[1]%10000000;
d[2]=d[2]+c[5]*i5+c[6]*i6+c[7]*i7+c[8]*i8+c[9]*i9;
//高位之和
x1=d[0];
y1=d[1];
z1=d[2];
d[2]="
+d[2]);
if(d[2]/10000000>
0)break;
//如果高位多于7位,该数超过21位,不符要求,退出
for(intj=0;
10;
j++)g[j]=0;
//准备计数字的个数
//System.out.println(d[2]+"
+d[1]+"
for(intk1=0;
k1<
3;
k1++){
for(intk=6;
=0;
k--){
y=1;
for(intk0=1;
k0<
=k;
k0++)y=y*10;
x=d[k1]/y;
//取高位的一个数字
//System.out.print("
d[k1]="
+d[k1]+"
y="
+y+"
x="
+x);
d[k1]=d[k1]%y;
//取高位的一个数字后余数
d[k1]="
+d[k1]);
g[x]=g[x]+1;
//计数字x出现的次数
//System.out.println(x+"
g["
+x+"
]="
+g[x]);
}}
//System.out.println(g[0]+"
+g[1]+"
+g[2]+"
+g[3]+"
+g[4]+"
+g[5]+"
+g[6]+"
+g[7]+"
+g[8]+"
+g[9]);
if((g[0]==i0)&
(i0<
10)&
(g[1]==i1)&
(g[2]==i2)&
(g[3]==i3)&
(g[4]==i4)&
(g[5]==i5)&
(g[6]==i6)&
(g[7]==i7)&
(g[8]==i8)&
(g[9]==i9))
解:
+z1+"
+y1+"
+x1);
程序3:
本程序运行时间9秒,启动多个线程计算。
p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 回溯法 回溯