【問題1】 カエル(●)の配置 ●●●○○○ ○○○●●● ●●●○○○ ○○○●●● ○●●○○● ●○○●●○  考え方:上位の4行は自由に配置し、下位の2行で条件を合わせるようにした 【問題2】 (答え)   解の数    3004通り。ただし、鏡像解を別解としてカウントする場合は24032通り。   美しい配置  ”美しい”の定義をどう考えるかによるが、          ”対対称解”という意味では、解は存在しない。          ”シンプルな解”と解釈すると、以下の配置あたりが候補になるかも        ○○●●●○        ●●●○○○        ○○○●●●        ●●●○○○        ○○○●●●        ●●○○○●         ○○○●●●        ●●○○○●        ●●○○○●        ○○●●●○        ○○●●●○        ●●●○○○ (解法)   プログラムによる探索で全数を求めた。以下に、プログラムの基本的なアルゴリズムを説明する。 (1)準備   6x6の領域を3x3の4つの領域A,B,C,Dに分けて考える。3x3の領域の中に配置されたカエルの   数を#(領域)で表すことにする。      +−−−+−−−+      |   |   |     #(A)+ #(B) = 9      | A | B |     #(C)+ #(D) = 9      |   |   |     #(A)+ #(C) = 9      +−−−+−−−+     #(B)+ #(D) = 9      |   |   |      | C | D |     #(A)= αとすると      |   |   |     #(D)= α、 #(B)= #(C)= 9−α      +−−−+−−−+     となる   対角線上には、カエルが3匹存在しなければならないので、#(A)+ #(D)>=3    これより、α>=2  ....@   また、鏡像解を除外するため、      Y軸対称を除外するために#(A)<=#(B)とする。 これより、α<=4  ....A      (Y= X)軸対称性と(Y=−X)軸対称性は後述する   3x3の領域に可能なカエルの配置を整理して、構造体配列 M[α][ ]を作成する。       M[α][ ]の構成要素を{p,u,v,x1,x2,x3,y1,y2,y3}とする        p:9ビットのカエルの配置(下記の□を0/1で表す。1がカエルが存在する)        α:3x3の領域内のカエルの数             v             /       □ □ □ → x1       □ □ □ → x2       □ □ □ → x3        ↓ ↓ ↓ \       y1 y2 y3  u         x1、x2、x3:X軸方向に存在するカエルの数       y1、y2、y3:Y軸方向に存在するカエルの数       u    :斜め方向(右下がり)に存在するカエルの数        v    :斜め方向(右上がり)に存在するカエルの数    例えば、p=B’011011000’(0xd8)の場合(ビット位置は、右下がMSB)       ○○○     x1=0   y1=2  u=1  α=4          ●●○     x2=2   y2=2  v=2       ●●○     x3=2   y3=0       M[4][n]={0xd8,1,2,0,2,2,2,2,0}となる   以上は、探索を効率よく行うための準備である。   (2)探索   探索は、4つの領域A,B,C,Dの要素を配列Mから取り出して、6x6の配置を生成し、条件に合致する   ものを選びだせばよい。   ただし、探索の効率の面から以下の条件で折り込む     − #(A)は、2<=α<=4の範囲でよい(上記の@,Aより)     − #(B),#(C)は、9−α、#(D)はαの範囲     − 鏡像解を除外するため、(Y= X)軸対称性と(Y=−X)軸対称性をチェックする        Aのu>=2 は除外する(Aのu<Dのuとして鏡像解を除外する)        Bのv>=2 は除外する(Bのv<Cのvとして鏡像解を除外する) ------(以下は探索プログラム)------------------------------------------------------------------------- ##### 20004.03.28 # def exe() : out = open("log.txt","w") M = Init() Total = 0 for n in range(2,5) : Cnt = Join(n,M,out) Total += Cnt WriteLog(out,"\n %d : %4d %4d" % (n,Cnt,Total)) out.close() ### def Init() : M = [[],[],[],[],[],[],[],[],[],[],[]] for k in range(0,512) : b = Bits(k) x1 = Bits(k & 0x07) x2 = Bits(k & 0x38) x3 = Bits(k & 0x1c0) y1 = Bits(k & 0x49) y2 = Bits(k & 0x92) y3 = Bits(k & 0x124) u = Bits(k & 0x111) v = Bits(k & 0x54) M[b] += [[k,u,v,x1,x2,x3,y1,y2,y3]] return M ### def Join(N,M,out) : Cnt = 0 for A in M[N] : [a,au,av,ax1,ax2,ax3,ay1,ay2,ay3] = A if au >= 2 : continue for D in M[N] : [d,du,dv,dx1,dx2,dx3,dy1,dy2,dy3] = D if au + du != 3 : continue for B in M[9-N] : [b,bu,bv,bx1,bx2,bx3,by1,by2,by3] = B if bv >= 2 : continue if ax1+bx1 != 3 : continue if ax2+bx2 != 3 : continue if ax3+bx3 != 3 : continue if dy1+by1 != 3 : continue if dy2+by2 != 3 : continue if dy3+by3 != 3 : continue for C in M[9-N] : [c,cu,cv,cx1,cx2,cx3,cy1,cy2,cy3] = C if bv + cv != 3 : continue if ay1+cy1 != 3 : continue if ay2+cy2 != 3 : continue if ay3+cy3 != 3 : continue if dx1+cx1 != 3 : continue if dx2+cx2 != 3 : continue if dx3+cx3 != 3 : continue Cnt += 1 if (N == 2) : printMap(out,Cnt,a,b,c,d) return Cnt ### def Bits(K) : w = K c = 0 while w != 0 : c += 1 w = w & (w-1) return c ### def printMap(out,Cnt,a,b,c,d) : Line ="\n%4d [%3x,%3x,%3x,%3x]" % (Cnt,a,b,c,d) WriteLog(out,Line) printMap2(out,((a>>0) & 0x007) + ((b<<3) & 0x38)) printMap2(out,((a>>3) & 0x007) + ((b>>0) & 0x38)) printMap2(out,((a>>6) & 0x007) + ((b>>3) & 0x38)) printMap2(out,((c>>0) & 0x007) + ((d<<3) & 0x38)) printMap2(out,((c>>3) & 0x007) + ((d>>0) & 0x38)) printMap2(out,((c>>6) & 0x007) + ((d>>3) & 0x38)) def printMap2(out,Map) : m = Map C = ["○","●"] Line = " " for n in range(0,6) : Line += C[(m & 0x01)] m = m >> 1 WriteLog(out,Line) ### def WriteLog(out,Line) : print Line out.write(Line+"\n") out.flush() ----------------------------------------------------------------------------------------------