從itpub看來的一道組合題
有人在 itpub論壇(http://www.itpub.net/thread-2086095-1-1.html) 提出如下問題
現有兩個表:a表,c表。 a表裡存有7碼組合,大約有六百多萬條。 c表裡有13條記錄,每條記錄是5碼的組合: 10 16 19 20 34 10 14 19 25 32 8 17 25 33 34 6 18 22 23 33 1 6 14 17 29 21 22 24 29 34 2 16 17 30 32 2 13 14 18 29 15 22 23 25 34 6 12 21 26 29 14 17 22 30 33 1 4 9 18 22 13 15 16 32 34 從a表選出與c表中的每一個組合的相同數等於1的7碼 組合。 比如從a表選出一組:4 13 17 19 21 23 28 這一組與c表的每一個組合的相同數都是一個數,與第一組的相同數是19,與第二組的想同數是19,與第三組的相同數是17,與第四組的相同數是23,與第五組的相同數是17,與第六組的相同數是21,與第七組的相同數是17,與第八組的相同數是13,與第九組的相同數是 23,與第十組的相同數是21,與第十一組的相同數是17,與第十二組的相同數是4,與第十三組的相同數是13,它們的相同個數都是1。 要求從a表選出符合這樣條件的7碼組合。
他的問題我已經用bitand位操作解決了。
with c as (select power(2,10)+power(2,16)+power(2,19)+power(2,20)+power(2,34) code1 from dual), a as(select power(2,19) code from dual union select power(2,31) code from dual union select power(2,10)+power(2,16) code from dual) select code from a,c where bitand(code,code1) in (select power(2,level) from dual connect by level<=63)
分析
感覺這種組合是可以完全列舉出來的,看有什麼辦法。
設13種組合分別是集合A-N,如果集合X符合要求,那麼(X &A)|(X &B)······| (X &N)=X
,且每個括號都是單個元素。
把1~34各數在13個組合中的存在情況分類,找出允許的值,然後依次確定第1~7個數,如果中途超過,則轉下一個
c=[ 10 16 19 20 34 10 14 19 25 32 8 17 25 33 34 6 18 22 23 33 1 6 14 17 29 21 22 24 29 34 2 16 17 30 32 2 13 14 18 29 15 22 23 25 34 6 12 21 26 29 14 17 22 30 33 1 4 9 18 22 13 15 16 32 34 ]; d=Array{Array{Int}}(34); p=zeros(Int,34); for x in 1:34 #d[x]=Array{Int}(34) #map(n->d[x][n]=0,1:34); d[x]=zeros(Int,34) for i in 1:13 for j in 1:5 #if x==c[(i-1)*5+j] d[x][j]=i end if x==c[i,j] p[x]=p[x]+1;d[x][p[x]]=i end end end end for x in 1:34 if p[x]>0 println(x) end end
從1開始的過程
julia> dt=Dict{Int,Int}() Dict{Int32,Int32} with 0 entries julia> map(x->if p[x]>0 dt[x]=1 end,1:34) 34-element Array{Any,1}: 1 1 nothing 1 nothing julia> dt Dict{Int32,Int32} with 27 entries: 32 => 1 25 => 1 19 => 1 33 => 1 24 => 1 julia> n=Dict{Int,Int}() Dict{Int32,Int32} with 0 entries julia> n[1]=pop!(dt,1) 1 julia> d[1] 34-element Array{Int32,1}: 5 12 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[1][1],1:5]) 5-element Array{Any,1}: nothing 1 1 1 1 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[1][2],1:5]) 5-element Array{Any,1}: nothing 1 1 1 1 julia> dt Dict{Int32,Int32} with 18 entries: 32 => 1 25 => 1 19 => 1 33 => 1 24 => 1 15 => 1 10 => 1 20 => 1 26 => 1 2 => 1 16 => 1 12 => 1 13 => 1 8 => 1 23 => 1 21 => 1 30 => 1 34 => 1 julia> n[2]=pop!(dt,2) 1 julia> d[2] 34-element Array{Int32,1}: 7 8 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[2][1],1:5]) 5-element Array{Any,1}: nothing 1 nothing 1 1 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[2][2],1:5]) 5-element Array{Any,1}: nothing 1 nothing nothing nothing julia> dt Dict{Int32,Int32} with 13 entries: 25 => 1 19 => 1 33 => 1 24 => 1 15 => 1 10 => 1 20 => 1 26 => 1 12 => 1 8 => 1 23 => 1 21 => 1 34 => 1 julia> n Dict{Int32,Int32} with 2 entries: 2 => 1 1 => 1 julia> n[8]=pop!(dt,8) 1 julia> d[8] 34-element Array{Int32,1}: 3 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[8][1],1:5]) 5-element Array{Any,1}: nothing nothing 1 1 1 julia> n[10]=pop!(dt,10) 1 julia> n Dict{Int32,Int32} with 4 entries: 10 => 1 8 => 1 2 => 1 1 => 1 julia> d[10] 34-element Array{Int32,1}: 1 2 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[10][1],1:5]) 5-element Array{Any,1}: nothing nothing 1 1 nothing julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[10][2],1:5]) 5-element Array{Void,1}: nothing nothing nothing nothing nothing julia> dt Dict{Int32,Int32} with 6 entries: 24 => 1 15 => 1 26 => 1 12 => 1 23 => 1 21 => 1 julia> n[12]=pop!(dt,12) 1 julia> d[12] 34-element Array{Int32,1}: 10 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[12][1],1:5]) 5-element Array{Any,1}: nothing nothing 1 1 nothing julia> dt Dict{Int32,Int32} with 3 entries: 24 => 1 15 => 1 23 => 1 julia> n Dict{Int32,Int32} with 5 entries: 10 => 1 12 => 1 8 => 1 2 => 1 1 => 1 julia> n[15]=pop!(dt,15) 1 julia> d[15] 34-element Array{Int32,1}: 9 13 julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[15][1],1:5]) 5-element Array{Any,1}: nothing nothing 1 nothing nothing julia> map(x->if haskey(dt,x) pop!(dt,x) end,c[d[15][2],1:5]) 5-element Array{Void,1}: nothing nothing nothing nothing nothing julia> dt Dict{Int32,Int32} with 1 entry: 24 => 1 julia> n Dict{Int32,Int32} with 6 entries: 15 => 1 10 => 1 12 => 1 8 => 1 2 => 1 1 => 1 julia> n[24]=pop!(dt,24) 1 julia> n Dict{Int32,Int32} with 7 entries: 24 => 1 15 => 1 10 => 1 12 => 1 8 => 1 2 => 1 1 => 1
上述步驟有些繁瑣,而且選擇下一個數有盲目性。其實每個數字都有互斥的數,這個排除應該高效一點。
ca=Array{Dict{Int,Int}}(34); map(z->(ca[z]=Dict{Int,Int}();map(x->ca[z][x]=1,1:34)),1:34); for i in 1:13 for j in 1:5 map(x->if haskey(ca[c[i,j]],x) pop!(ca[c[i,j]],x) end,c[i,1:5]); end end function f(d::Dict{Int,Int},n::Int,m::Int,c::Int) #n last element, m set size d1=d; c1=c; if length(d)>=m if c1!=13 println(d) end; # no result of c1==13 return else for i in ca[n] #println(i[1]) #key of dict if !haskey(d1,i[1]) d1[i[1]]=1; f(d1,i[1] ,m,c1+ countnz(d[i[1]])) pop!(d1,i[1]); end end end end d0=Dict{Int,Int}(); d0[1]=1; f(d0,1,4, countnz(d[1])) #f(d0,1,7, countnz(d[1])) #about 5 minues with no result
上述程式在不規定出現總次數時能輸出,規定13次則無輸出,錯在d的區域性變數覆蓋了全域性變數,countnz(d[i[1]]
實際上成了已選數,而不是組數。還有其他條件也沒有寫。
用Dict查詢比較浪費,改用陣列實現,實際上就是用2進位制位來判斷已用和未用
c=[ 10 16 19 20 34 10 14 19 25 32 8 17 25 33 34 6 18 22 23 33 1 6 14 17 29 21 22 24 29 34 2 16 17 30 32 2 13 14 18 29 15 22 23 25 34 6 12 21 26 29 14 17 22 30 33 1 4 9 18 22 13 15 16 32 34 ]; d=Array{Array{Int}}(34); p=zeros(Int,34); for x in 1:34 #d[x]=Array{Int}(34) #map(n->d[x][n]=0,1:34); d[x]=zeros(Int,34) for i in 1:13 for j in 1:5 #if x==c[(i-1)*5+j] d[x][j]=i end if x==c[i,j] p[x]=p[x]+1;d[x][p[x]]=i end end end end for x in 1:34 if p[x]>0 println(x) end end da=Array{Array{Int}}(34); map(z->(da[z]=1:34;map(x->da[z][x]=1,1:34)),1:34); for i in 1:13 for j in 1:5 map(x->da[c[i,j]][x]=0,c[i,1:5]); end end function pf(d::Array{Int}) map(x->if d[x]==1 print(" ",x) end ,1:34) println(""); end function fun(d::Array{Int},f::Array{Int},n::Int,m::Int,c::Int) #n last element, m set size #d1=d; d1=Array{Int}(34) copy!(d1,d) if countnz(d)>=m if c==13 pf(d) end; # no result of c1==13 return end #println(f) for i in n:34 #ca[n] #println(i[1]) #key of dict if sum(da[i])<34 && f[i]==1 #can use d1[i]=1; f1=(f .& da[i]) #pa1 is array of pair #println("\nd1",d1,"\nf1",f1) if countnz(f1)>0 #println("i=",i); fun(d1,f1,i ,m,c+ p[i]); end d1[i]=0; end end end a0=zeros(Int,34); a0[1]=1; fun(a0,da[1],1,2,(p[1])) @time fun(a0,da[1],1,6,(p[1])) @time fun(a0,da[1],1,7,(p[1])) @time map(x->(if sum(da[x])<34 a0=zeros(Int,34);a0[x]=1;fun(a0,da[x],x,7,(p[1]))end),1:34)
執行結果
julia> @time fun(a0,da[1],1,6,(p[1])) 1 2 10 15 21 33 1 2 15 19 21 33 0.064445 seconds (35.56 k allocations: 1.228 MiB) julia> @time fun(a0,da[1],1,7,(p[1])) 1 2 10 12 15 24 33 1 2 10 15 24 26 33 1 2 12 15 19 24 33 1 2 15 19 24 26 33 1 8 10 13 21 23 30 1 8 13 19 21 23 30 0.093311 seconds (38.09 k allocations: 1.314 MiB)
相關文章
- 通過一道題來看React事件模型React事件模型
- 從一道Promise執行順序的題目看Promise實現Promise
- 一道好玩的組合數學的推公式題(綠名題, 1879C - Make it Alternating公式
- 從一道筆試題題說起筆試
- 從一道題來看看golang中的slice作為引數時的現象Golang
- 從 Google 的一道面試題說起·Go面試題
- 從例子來看BFC
- 從一道面試題探究 Integer 的實現面試題
- 從一道前端面試題談起前端面試題
- 千頭萬緒:從一道面試題看資料庫效能和安全的方方面面面試題資料庫
- 從 VNCTF2024 的一道題學習QEMU EscapeVNCTF2
- 從一道PG知識的選擇題談起
- 來聊一道前端面試題吧前端面試題
- 組合數問題
- 演算法分析:看雪CTF2019的一道逆向題目演算法TF2
- 從一道場景面試題談起面試題
- 從一道前端面試題引發的原理性探究前端面試題
- 從老鼠試毒問題來看二分法
- 小於n的最大數,記一道位元組面試題面試題
- 從來沒有一種技術是為了解決複用、靈活組合、定製開發的問題
- 從一道面試題談 Array.prototype.push()面試題
- 從一道春招筆試題說起 [上]筆試
- 字串排列組合問題字串
- 一道關於二叉樹的位元組面試題的思考二叉樹面試題
- 業務的未來是可組合的 - Gartner
- 從 Discord 看未來社交的「超級群」模式模式
- 看來我是真的不適合華為系的。。。
- ITPUB的採訪稿
- 一道題
- 從鏈式呼叫到管道組合
- 一道簡單的題
- 一道新奇的招聘題
- JavaScript的一道加法題?JavaScript
- 【看雪課程】組合語言,開課啦!組合語言
- 從卷積拆分和分組的角度看CNN模型的演化卷積CNN模型
- 組合雙射題選做
- 組合計數思維題
- 2024.4.6 組合數學補題
- 組合數輸出題解