编程之美:第四章 数字之趣 4.10数字哑谜和回文

来源:互联网 发布:香港青旅 知乎 编辑:程序博客网 时间:2024/05/22 01:34
/*数字哑谜和回文:1神奇的9位数。能不能找出符合如下条件的9位数:这个数包括了1~9这9个数字;这个9位数的前n位都能被n整除,若这个数表示为abcdefghi,则ab可以被2整除,abc可以被3整除......abcdefghi可以被9整除2有这样一个乘法算式:人过大佛寺*我=寺佛大过人这里面每一个字都代表着一个数字,并且不同的字代表的数字不同,你能把这些数字都找出来吗?分析:问题1的解法1:假设这个9位数是abcdefghi,,诶个字符对应1~9之间的数。可以考虑剪枝来优化性能。剪枝=避开死胡同,把搜索比作遍历一棵树,那么剪枝就是讲数中的一些不能到达的枝条剪掉。比如循环到b等于奇数时,ab必须被2整除,b必须为偶数。问题1的解法2:试一试用逻辑推理的办法来求解这个问题,假设每个字符目前都可以对应1~9之间的任何数字。a    1 2 3 4 5 6 7 8 9b    1 2 3 4 5 6 7 8 9c    1 2 3 4 5 6 7 8 9d    1 2 3 4 5 6 7 8 9e    1 2 3 4 5 6 7 8 9f    1 2 3 4 5 6 7 8 9g    1 2 3 4 5 6 7 8 9h    1 2 3 4 5 6 7 8 9i    1 2 3 4 5 6 7 8 9把整除的条件列出来,a被1整除,任何数都满足这个条件,b为0,2,4,6,8abc必须被3整除,那么a+b+c=3*kabcd必须被4整除,那么d必须为2,4,6,8,cd被4整除abcde被5整除,e为5(0为什么不可能,因为是1~9,没有0)abcdef被6整除,f = 2,4,6,8,a+b+c+d+e+f=3*k,不易想到abcdefg被7整除,abcd -efg能被7整除(考虑到7能整除1001),不易想到abcdefgh被8整除,h = 2,4,6,8,fgh能被8整除,不易想到abcdefghi被9整除,a+b+c+d+e+f+g+h+i=9*k,不易想到范围如下:a 1 3 7 9b 2 4 6 8c 1 3 7 9d 2 4 6 8e 5f 2 4 6 8g 1 3 7 9h 2 4 6 8i 1 3 7 9下面条件:a+b+c被3整除cd被4整除d+e+f被3整除abcd-efg能被7整除fgh能被8整除因为d +e +f被3整除,而e = 5,则d + f = 3k + 1形式{d=2   {d=4  {d=6  {d=8{f=8   {f=6  {f=4  {f=2由于cd被4整除,cd=12,16,32,36,72,76,92,96d=2或6f=8或4fgh被8整除fgh=816,832,872,896,416,432,472,496f=8时,d=2,故h不能为2f=4时, d=6,故h不能为6fgh=816,896,432,472简化结果:a 1 3 7 9b 4 8c 1 3 7 9d 2 6e 5f 8 4g 1 3 7 9h 6 2i 1 3 7 9未使用的条件有:a+b+c被3整除,abcd-efg能被7整除(考虑到7能整除1001)cd  = 12,16,32,36,72,76,92,96df = 28,64输入:输出:381654729*//*关键:1 a被1整除,任何数都满足这个条件,b为0,2,4,6,8abc必须被3整除,那么a+b+c=3*kabcd必须被4整除,那么d必须为2,4,6,8,cd被4整除abcde被5整除,e为5(0为什么不可能,因为是1~9,没有0)abcdef被6整除,f = 2,4,6,8,a+b+c+d+e+f=3*k,不易想到abcdefg被7整除,abcd -efg能被7整除(考虑到7能整除1001),不易想到abcdefgh被8整除,h = 2,4,6,8,fgh能被8整除,不易想到abcdefghi被9整除,a+b+c+d+e+f+g+h+i=9*k,不易想到a 1 3 7 9b 2 4 6 8c 1 3 7 9d 2 4 6 8e 5f 2 4 6 8g 1 3 7 9h 2 4 6 8i 1 3 7 92 printf("%d\n",nineBitNum_pruning());//后面剪枝的时候,选数已经有顺序了,因此不再适用剪枝*/#include <stdio.h>#include <string.h>bool isDifferent(int a,int b,int c,int d,int e,int f,int g,int h,int i){int iMark[10];memset(iMark,0,sizeof(iMark));iMark[a]++;iMark[b]++;iMark[c]++;iMark[d]++;iMark[e]++;iMark[f]++;iMark[g]++;iMark[h]++;iMark[i]++;for(int i = 1 ; i <= 9 ; i++){if(iMark[i] != 1){return false;}}return true;}int nineBitNum_base()//基本方法,剪枝的不多{int e = 5;for(int a = 1 ; a <= 9 ; a += 2){if(5 == a){continue;}for(int b = 2 ; b <= 8 ; b += 2)for(int c = 1; c <= 9 ; c += 2){if(5 == c){continue;}for(int d = 2 ; d <= 8 ; d += 2){for(int f = 2 ; f <= 8 ; f += 2)for(int g = 1 ; g <= 9 ; g += 2){if(5 == g){continue;}for(int h = 2 ; h <= 8; h += 2)for(int i = 1 ; i <= 9 ; i += 2){if(i == 5){continue;}//if((a + b + c) % 3 == 0 && (10*c + d) % 4 == 0 && (d + e + f) % 3 == 0 && (100*f + 10*g + h) % 8 == 0 && //(1000*a + 100*b + 10*c +d - 100*e - 10*f -g) % 7 == 0)  //(a*1e6 + b*1e5 + c*1e4 + d*1e3 + e*1e2 + 10*f + g) % 7 == 0)if((a + b + c) % 3 == 0 && (10*c + d) % 4 == 0 && (d + e + f) % 3 == 0 && (100*f + 10*g + h) % 8 == 0 && (a*1000000 + b*100000 + c*10000 + d*1000 + e*100 + f*10 + g) % 7 == 0&& isDifferent(a,b,c,d,e,f,g,h,i)){return (a*1e8 + b*1e7 + c*1e6 + d*1e5 + e*1e4 + f*1e3 + g*1e2 + h*1e1 + i);}}}}}}return -1;}long nineBitNum_pruning()//pruning剪枝,限制条件更多{int e = 5;for(int a = 1 ; a <= 9 ; a += 2){if(5 == a){continue;}for(int b = 4 ; b <= 8 ; b += 4){for(int c = 1; c <= 9 ; c += 2){if(5 == c){continue;}for(int d = 2 ; d <= 6 ; d += 4){for(int f = 4 ; f <= 8 ; f += 4){for(int g = 1 ; g <= 9 ; g += 2){if(5 == g){continue;}for(int h = 2 ; h <= 6; h += 4){for(int i = 1 ; i <= 9 ; i += 2){if(i == 5){continue;}if((a + b + c) % 3 == 0 && (1000*a + 100*b + 10*c + d - 100*e - 10*f -g) % 7 == 0 && isDifferent(a,b,c,d,e,f,g,h,i)){return (long)(a*1e8 + b*1e7 + c*1e6 + d*1e5 + e*1e4 + f*1e3 + g*1e2 + h*1e1 + i);}}}}}}}}}return -1;}int isValid(int a,int b,int c,int d,int e,int f,int g,int h,int i){if((a + b + c) % 3 == 0 && (1000*a + 100*b + 10*c + d - 100*e - 10*f -g) % 7 == 0 && isDifferent(a,b,c,d,e,f,g,h,i)){return (long)(a*1e8 + b*1e7 + c*1e6 + d*1e5 + e*1e4 + f*1e3 + g*1e2 + h*1e1 + i);}return -1;}void process(){printf("%d\n",nineBitNum_base());//printf("%d\n",isValid(3,8,1,6,5,4,7,2,9));//printf("%d\n",nineBitNum_pruning());//后面剪枝的时候,选数已经有顺序了,因此不再适用剪枝}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击