while True:

問題20

直交座標系 xyz において 𝑥, 𝑦, 𝑧 の値がいずれも整数(負の整数およびゼロを含む)であるすべての点に原子が配置されているとする. 任意の点の座標 (𝑥0, 𝑦0, 𝑧0) 長さ d を読み込み,この点を中心とする半径 d の球内にある原子の総数を数えるプログラムを作れ. ただし,球の中心の座標と半径は実数とする.

難易度 ★★★★☆

やや発展的な問題です。方法さえわかれば簡単だと思います。格子点を数え上げればよいです。今回の場合、格子点がある可能性があるのは、 x, y, zを中心とした、1辺の長さが2dの立方体の中のはずです。つまり、これらの中の格子点から、 任意の点までの距離がd以下であればそれは球内の格子点といえることがわかります。
program question20
	implicit none
	integer :: x, y, z, start_x, end_x, start_y, end_y, start_z, end_z, counter
	real :: x0, y0, z0, d

	print *, "input xyz (x,y,z) :"
	read *, x0, y0, z0
	print *, "input distance :"
	read *, d

	! 座標を中心とする箱の生成
	counter = 0
	start_x = return_start(x0, d)
	start_y = return_start(y0, d)
	start_z = return_start(z0, d)

	end_x = return_end(start_x, d)
	end_y = return_end(start_y, d)
	end_z = return_end(start_z, d)

	! 箱内の格子点で距離内にあるものを数え上げる
	do x = start_x, end_x
		do y = start_y, end_y
			do z = start_z, end_z
				if (sqrt((x0 - x) ** 2 + (y0 - y) ** 2 + (z0 - z) ** 2) <= d) then
					counter = counter + 1
				end if
			end do
		end do
	end do

	print *, counter

	contains
		function return_start(key, distance)
			integer return_start
			real distance, key
			return_start = int(key - distance)
		end function

		function return_end(start_int, distance)
			integer return_end, start_int
			real distance
			return_end = int(start_int + (2 * distance) + 1)
		end function

end program question20		
ページのトップへ戻る