算法设计与分析:第五章 回溯法 5.7构造高精度数据

来源:互联网 发布:js对象数组重新赋值 编辑:程序博客网 时间:2024/06/18 11:12
/*构造高精度数据:构造一个尽可能大的数,使其从高到底前一位能被一整除,前2位能被2整除,...,前n位能被n整除分析:解空间:记高精度数据为a1a2...an,则(a1*10^(n-1) + a2*10^(n-2) + ... + an)整除n如何搜索?从高位到低维逐位尝试,失败回溯的算法。算法的首位从1开始枚举,以后各位从0开始枚举。生成的高精度数据用数组从高位到低位存储,一号元素存储最高位。如何确定和保留最优解?用数组A作为当前求解的高精度数据的暂存处。数组B为当前最大的满足条件的数。求解出的满足条件的睡之间只需要比较位数就能确定大小。n为当前满足条件的最大数据的位数,当i > n时,位数多数据一定大;i = n时,由于搜索是由小到大金星的,位数相等时后来满足条件的数据一定比前面的大。输出:447204888644483284*//*关键:1 设置数组首位为1 A[1] = 1;2 循环退出条件为A[1] > 9 ,while(A[1] <= 9)//因为最后会回溯到A[1],而A[1]的值最多为93 当 i >= n时,更新数据if(i >= n)//寻找到更大的数据,将临时数组中的数据保存到最终数据中{n = i ;//更新n4 检查第i位是否符合条件r = r % i;//获取第i位的余数if(r != 0)//第i位失败5 构造第i位可能的解//构造第i位的可能解,也就是加上i-r,构成i缺少的部分A[i] = A[i] + i - r;6 确定第i位是否需要回溯,是当其值大于9,并且位数大于1while(A[i] > 9 && i > 1)//搜索到第i位的解,回溯到前一位7 回溯的做法是:另当前位为0,A[i] = 0 , 再减小位数;i--,另上一位可能解为:A[i] = A[i] + i;A[i] = 0;//置当前位为0i = i - 1;A[i] = A[i] + i;//?尝试前一位,加i的原因是,在前一位的基础上加i,上一位必定能被i整除。*/#include <iostream>#include <string.h>using namespace std;void num(){//设置数组,用于暂存int A[101] , B[101];//初始化数组memset(A, 0 , sizeof(A));memset(B, -1 , sizeof(B));//设置暂存数组的首位为1A[1] = 1;int i = 1;int n = 1;while(A[1] <= 9)//因为最后会回溯到A[1],而A[1]的值最多为9{if(i >= n)//寻找到更大的数据,将临时数组中的数据保存到最终数据中{n = i ;//更新nfor(int k = 1 ; k <= n ; k++){B[k] = A[k];}}i = i + 1;int r = 0;for(int j = 1 ; j <= i ; j++)//检查第i位是否符合条件{r = r * 10 + A[j];}r = r % i;//获取第i位的余数if(r != 0)//第i位失败{//构造第i位的可能解,也就是加上i-r,构成i缺少的部分A[i] = A[i] + i - r;while(A[i] > 9 && i > 1)//搜索到第i位的解,回溯到前一位{A[i] = 0;//置当前位为0i = i - 1;A[i] = A[i] + i;//?尝试前一位,加i的原因是,在前一位的基础上加i,上一位必定能被i整除。}}}for(int i = 1 ; i < 101 ; i++){if(B[i] == -1){break;}cout << B[i] ;}cout << endl;}void process(){num();}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0