東京理科大学 infoserv[更新日]1999.04.30


問9  次の Fortran プログラムの説明及びプログラムを読んで,設問に答えよ。

〔プログラムの説明〕

4 次の魔方陣を作るプログラムである。N 次の魔方陣とは,N×N の 目(方陣)に1 から N2 までの整数を重複のないように埋めてゆき,縦,横,対角線に並んだどの N個の整数の和もある値 S と等しくなるようにしたものである。値 S は,N2 個の整数の総和 N2 (N2+1)/2 を列数 N で割った値 N (N2+1)/2 である。図は 3次の魔方陣の例で, S は15である。

2

9

4

7

5

3

6

1

8

図 3次の魔方陣の例

(1) 主プログラムでは,魔方陣のための配列 p を 1 次元配列として扱う。 配列 p の要素数は,方陣用の N2 個に順列生成のために必要とな る 1 個を加えた,合計 N2+1 個である。この配列 p の各要素を 昇順の数列で初期化する。

(2) 主プログラムの行番号 8 〜 20 のループ部では,Fischer-Krause の アルゴリズムに従い,配列 p の要素を並べ替えることで,順列を次々に生成 している。このループでは関数 hantei と,サブルーチン swap 及び reverse を呼び出している。

(3) 関数 reshape(p,(/N,N/)) は,配列 p の最初の N2 個の 要素を N×N の 2 次元配列に変換する。この 2 次元配列を引数とした関数 hantei では,縦,横,対角線についてそれぞれの数の和を計算し,それが S と一致しているかどうかを判定している。N 通りの縦の和,N 通りの横の和, 2 通りの対角線の和のすべてが S と一致した場合にこの方陣は魔方陣である と判定し,値 1 を返す。それ以外の場合には,値 0 を返す。

(4) サブルーチン swap(i,j) は,二つの変数 i,j の値を交換する。

(5) サブルーチン reverse(p,i) は,配列 p の最初の i 個の要素を逆順に並べ替える。

(6) 主プログラムでは,関数 hantei の戻り値が 1 のときに配列 p を出力して終了する。

〔プログラム〕
(行番号)
01  program mahoujin
02        integer, parameter :: N=4, N2=N*N, NP=N2+1, S=N*(N2+1)/2
03        integer, dimension (NP) :: p
04        integer :: i, j, k
05        do i=1,NP
06          p(i)=i
07        enddo
08        do while(hantei(N,reshape(p,(/N,N/)),S) /= 1)
09          i=2
10          do while(p(i) < p(i-1))
11             i=i+1
12          enddo
13          if(i > N2) stop
14          j=1
15          do while(p(j) > p(i))
16             j=j+1
17          enddo
18          call swap(p(i),p(j))
19          call reverse(p,i-1)
20        enddo
21        write(*,'(4i5)') (p(k),k=1,N2)
22  contains
23  !
24        function hantei(N, q, S)
25        integer :: hantei, N, S
26        integer, dimension (:, :) ::  q
27        integer :: sum1, sum2, sum3, sum4, i, j
28        hantei=0 
29        sum1=0
30        sum2=0
31        do i=1,N
32          sum3=0
33          sum4=0
34          do j=1,N
35            sum3=sum3+q(i,j)
36            sum4=sum4+ 
37          enddo
38          if((sum3 /= S) .or. (sum4 /= S)) return
39          sum1=sum1+ 
40          j= 
41          sum2=sum2+q(i,j)
42        enddo
43        if((sum1 /= S) .or. (sum2 /= S)) return
44        hantei=1
45        end function hantei
46  !
47        subroutine reverse(p,i)
48        integer :: i, k
49        integer, dimension (i) :: p
50        do k=1,i/2
51          call swap(p(k), )
52        enddo
53        end subroutine reverse
54  !
55        subroutine swap(i,j)
56        integer :: i,j,tmp
57        tmp=i
58        i=j
59        j=tmp
60        end subroutine swap
61  ! 
62  end program mahoujin
 

設問 プログラム中の に入れる 正しい答えを,解答群の中から選べ。

a,b に関する解答群

ア q(1,j)    イ q(i,1)    ウ q(i,i)

エ q(i,j)    オ q(j,1)    カ q(j,i)

c に関する解答群

ア 1     イ i      ウ N

エ N+1    オ N+1-i    カ N+i

 

d に関する解答群

ア p(1)      イ p(i)      ウ p(i-k)

エ p(i-k+1)    オ p(k+i/2)    カ p(k*2)


東京理科大学 infoserv 戻る 次頁:問10