能实现本题要求的公式: 公式1使用整数位数固定法,长度172个字符: =--MID(SMALL(10^6+TEXT(FREQUENCY(MMULT($A$2:$G$2,INT(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2))),ROW($1:$700))*10^3+ROW($1:$701),"[<999]1!e6"),MIN(ROW(A1),701)),29-3*COLUMN(),3) 公式2使用小数尾数固定法,长度173个字符: =--MID(SMALL(101+TEXT(FREQUENCY(MMULT($A$2:$G$2,INT(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2))),ROW($1:$700))-1+ROW($1:$701)/10^3,"[>];99")+1%%,MIN(ROW(A1),701)),29-3*COLUMN(),3) 公式3是178个字符(使用1!e6的方式后就变成公式1): =--MID(10^6+SMALL(TEXT(FREQUENCY(MMULT($A$2:$G$2,INT(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2))),ROW($1:$700))*10^3+ROW($1:$701)-1,"[<999]999999")+1,MIN(701,ROW(A1))),29-3*COLUMN(),3) 本题只是规定不能使用条件格式或自定义格式这2种方式来屏蔽0,所以以上公式可以在工具选项中的视图/窗口选项中取消"零值"的勾选来不显示0,以上三个公式都是采用这种设置. 也可以用公式来屏蔽0值,公式4长度为183个字符: =TEXT(MID(SMALL(10^6+TEXT(FREQUENCY(MMULT($A$2:$G$2,--(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2)>=1)),ROW($1:$700))*10^3+ROW($1:$701),"[<999]1!e6"),MIN(ROW()-1,701)),29-3*COLUMN(),3),"#;") --由于嵌套限制,所以用--代替INT(嵌套限制针对函数,不针对运算符) 最短的公式是(162个字符,但速度太慢,所以只作为一种思路介绍): =--MID(SMALL(10^9+TEXT(FREQUENCY(MMULT($A$2:$G$2,MOD(INT(COLUMN($A:$DW)*2/2^ROW($1:$7)),2)),ROW($1:$65535))*10^6+ROW(A:A),"[<10e5]1!e9"),ROW(A1)),56-6*COLUMN(),3) 下面解释一下以上公式和本题用到的主要关键点. 关键点1: 为取得所有的组合所以需要产生一个数组B(但需要主要的是下面这个数组可以有多种方向,知识点3就是利用了这一点) 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 ...... 1 1 1 1 1 1 1 然后逐个和A2:G2(数组A)相乘相加(使用函数mmult)就能得到各个组合之和. 关键点2: mmult函数对2个相乘数组Amn Bxy的要求是n=x,为了不使用TRANSPOSE减少公式长度,所以直接用mmult(数组A,数组B),由于数组A=1*7,所以要求数组B是7*127,这样结果就是1*127的数组组合之和. 关键点3: 产生一个大小方向是怎样的数组, COLUMN($A:$DW)/2^ROW($1:$7)是得到7*127数组的最短公式,COLUMN($A:$DW)是127列,除ROW(1:7)后得到7行127列.其中一个技巧是用2^ROW($1:$7)/2代替2^(ROW($1:$7)-1)能减少字符,所以最后公式是COLUMN($A:$DW)*2/2^ROW($1:$7) 大小方向是指下面几种数组: 所以使用COLUMN(A:DW)还是ROW(1:127), 用ROW(1:7)还是COLUMN(A:G)是本题关键之一,这影响到MMULT的相乘方式. 关键点4:(28,29期的考点) 由于一共有7个单元格,且每格单元格最大为99,所以最大组合之和=7*99=693,所以可以用Frequency来求得1:693出现的次数. 关键5: 将用freq产生的次数和对应和进行组合.组合串S=次数 与 和,组合方式有两种一种是S1=次数*10^3+和,另一种是S2=次数+和/10^n 所有答案都考虑到了4和5. 关键点6: 使用TEXT函数的判断功能将重复的和区分出来,在S1中用"<".S2用">",这里比较关键的是TEXT和S组合和方式的协同方式. 更好地使用一些技巧,比如e指数(S1中)和%(S2中),或使用 -1 ..."99"..+1, 能进一步减少字符. 关键点7:(也是29期的考点) 使用MIN来解决SMALL个数不够时的出错问题. 关键点8:(29期也用到了) 根据列的不同,使用MID来取得结果,主要解决MID的第二参数问题. 本期题的公式中虽然只出现了一次A2:G2,但围绕着A2:G2却需要进行一连串的变换,考虑公式时要注意各个函数之间的协同,这也是出本题的目的之一.
下面以公式4为例简单解释一下公式原理: 公式4=TEXT(MID(SMALL(10^6+TEXT(FREQUENCY(MMULT($A$2:$G$2,--(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2)>=1)),ROW($1:$700))*10^3+ROW($1:$701),"[<999]1!e6"),MIN(ROW()-1,701)),29-3*COLUMN(),3),"#;") 无中生有 a=--(MOD(COLUMN($A:$DW)*2/2^ROW($1:$7),2)>=1) --生成用来取值的01数组. 各取所需 b=MMULT($A$2:$G$2,a) --和01相乘相加取得所有组合之和. 大海捞针 c=FREQUENCY(b,ROW($1:$700)) --求出各个和的次数,在b中没有的次数为0,内存结果数组行数为701行. 相依为命 d=c*10^3+ROW($1:$701) --将次数和"和"组合. 唇亡齿寒 e=text(d,"[<999]1!e6") --次数(c)为0的改成10^6,其他按原来的. 取长补短 f=10^6+e --固定字符位数,为MID取数做准备. 捉襟见肘 g=MIN(ROW()-1,701) --由于c的函数是701,所以当大于701时small会出错,用min来限制. 以小欺大 h=small(f,g) --从小到大逐个取出. 偷梁换柱 i=29-3*COLUMN() --确定MID取数的起始位置. 随遇而安 j=MID(h,i) --取得对应的值 一夫当关 >>以下两个是锦上添花. k="#;" --屏蔽0值的格式
入乡随俗 Text(j,k) --取得最终结果
本次答题人数不多,所以多啰嗦了几句.
[此贴子已经被作者于2008-1-23 23:50:19编辑过] |