【经典编程题】
已知有8组一一对应的数(X,Y)如下,构成了一个字典库:
(5,1)
(6,2)
(7,4)
(8,8)
(9,16)
(10,32)
(11,64)
(2,128)
编程实现以下功能:
第一步:输入一个数Z;
第二步:在字典库中寻找多个Y值(范围:1、2、4、8、16、32、64、128),使Z=Y1+Y2+Y3+…….;查询字典库,并输出Y1,Y2,Y3…所对应的X1,X2,X3…….(注意:Y值的个数不确定)
第三步:判断Y值的个数,若Y值的个数为奇数个,则输出(4,X1,X2,X3….);若为偶数个,则输出(4,X1,X2,X3……,12)
示例1:
第一步:输入Z=32
第二步:Z=32,Y1=32,因此Y值个数为1个,查询字典库Y1所对应的X1=10
第三步:Y值个数为奇数个,输出(4,10)
示例2:
第一步:输入Z=96
第二步:Z=32+64,Y1=32,Y2=64,因此Y值个数为2个,查询字典库Y1、Y2所对应的X1=10,X2=11
第三步:Y值个数为偶数个,输出(4,10,11,12)
示例3:
第一步:输入Z=47
第二步:Z=32+8+4+2+1,Y1=32,Y2=8,Y3=4,Y4=2,Y5=1,因此Y值个数为5个,查询字典库Y1、Y2 、Y3、Y4、Y5所对应的X1=10,X2=8,X3=7,X4=6,X5=5
第三步:Y值个数为奇数个,输出(4,10,8,7,6,5)
难点在于第二步:如何确定Y值和Y值的个数?
思路分析1如下:
已知有8组一一对应的数(X,Y)如下,构成了一个字典库,将字典库中的Y值转换为二进制数如下:
(5,1)
(6,10)
(7,100)
(8,1000)
(9,10000)
(10,100000)
(11,1000000)
(2,10000000)
任意输入一个数Z,寻找字典库中多个Y值,使Z=Y1+Y2+Y3……….,在二进制上,也必然成立。反之,任何一个数Z必然能够被拆解为字典库中多个Y值之和。
例如:Z=47,二进制数为101111,拆解为101111=100000+1000+100+10+1,则可以知道:Z=47=32+8+4+2+1,因此找到了Y1=32,Y2=8,Y3=4,Y4=2,Y5=1。
Z=96,二进制数为1100000,拆解为1100000=1000000+100000,则可以知道:Z=47=64+32,因此找到了Y1=64,Y2=32。
Z=164,二进制数为10100100,拆解为10100100=10000000+100000+100,则可以知道:Z=164=128+32+4,因此找到了Y1=128,Y2=32,Y3=4。
思路分析2如下:
考虑所有的可能性结果并分析得到相关规律,编程实现以下功能:
第一步:输入一个数Z;
第二步:判断Z是奇数还是偶数,如果是奇数,则输出5并存入数组n[];如果是偶数则不输出
第三步:判断(Z+1)/4的余数是否为0或3,如果是,则输出6并存入数组n[];如果不是则不输出
第四步:判断(Z+1)/8的余数是否在(0或5<=X<=7)中,如果是,则输出7并存入数组n[];如果不是则不输出
第五步:判断(Z+1)/16的余数是否在(0或9<=X<=15)中,如果是,则输出8并存入数组n[];如果不是则不输出
第六步:判断(Z+1)/32的余数是否在(0或17<=X<=31)中,如果是,则输出9并存入数组n[];如果不在则不输出
第七步:判断(Z+1)/64的余数是否在(0或33<=X<=63)中,如果是,则输出10并存入数组n[];如果不在则不输出
第八步:判断(Z+1)/128的余数是否在(0或65<=X<=127)中,如果是,则输出11并存入数组n[];如果不在则不输出
第九步:判断Z是否在(128<=X<=200)中,如果在,则输出2并存入数组n[];如果不在则不输出
第十一步:判断数组n[]中元素的个数,如果是奇数个,则加入元素4;如果是偶数个,则加入元素4和12。
第十二步:输出数组n[](将其中元素从小到大进行排序)
思路分析3如下:
使用降维暴力搜索:将Z与所有Y值进行比较,紧挨着Z并小于Z的数Y1,用(Z-Y1)再与所有Y值比较,紧挨着并小于(Z-Y1)的数Y2,用(Z-Y1-Y2)再与所有Y值比较…直到Z降为0,则Y1、Y2、Y3…就是所求。
思路分析4如下:
已知存在以下数组:
a[1,3,5,7,9………]
b[2,3,6,7,10,11,14,15,18,19,]
c[。。。。。]
d[。。。。。]
e[。。。。。。]
f[。。。。。。。]
g[。。。。。]
h[。。。。。]
m[。。。。。]
编程实现以下功能:
第一步:输入一个数Z;
(第二步:判断Z是否在数组a[]中,如果在,则输出5并存入数组n[];如果不在则不输出)
判断Z是奇数还是偶数,如果是奇数,则输出5并存入数组n[];如果是偶数则不输出
第三步:判断Z是否在数组b[]中,如果在,则输出6并存入数组n[];如果不在则不输出
第四步:判断Z是否在数组c[]中,如果在,则输出7并存入数组n[];如果不在则不输出
第五步:判断Z是否在数组d[]中,如果在,则输出8并存入数组n[];如果不在则不输出
第六步:判断Z是否在数组e[]中,如果在,则输出9并存入数组n[];如果不在则不输出
第七步:判断Z是否在数组f[]中,如果在,则输出10并存入数组n[];如果不在则不输出
第八步:判断Z是否在数组g[]中,如果在,则输出11并存入数组n[];如果不在则不输出
第九步:判断Z是否在数组h[]中,如果在,则输出2并存入数组n[];如果不在则不输出
(第十步:判断Z是否在数组m[]中,如果在,则输出12并存入数组n[];如果不在则不输出)
第十一步:判断数组n[]中元素的个数,如果是奇数个,则加入元素4;如果是偶数个,则加入元素4和12。
第十二步:输出数组n[](将其中元素从小到大进行排序)
要求:C语言、Python、Go、C++实现,且用尽量少的程序代码。