DFSグリッドセグメンテーションJava

問題の説明

6x6グリッドの場合、グリッドの側面に沿って2つにカットします。 
2つのパーツは完全に同じ形状である必要があります。 
計算してみてください: 
合計でいくつの異なるセグメンテーション方法がありますか。 
注:回転対称性は同じセグメンテーション方法に属します。 
余分な内容や説明文なしでこの整数を提出してください。

透かし、type_d3F5LXplbmhlaQ、shadow_50、text_Q1NETiBAcXFfNTIzNjAwNjk =、size_20、color_FFFFFF、t_70、g_se、x_16

特定のアイデア

切断する必要のある2つの部分はまったく同じであるため、切断ルートはグラフの中心点を通過する必要があり、分割線は中心点に対して対称である必要がありますしたがって、図の交点を要素として使用し、6*6グリッドを7*7グリッドに変換して、中心点から境界dfsの深さまで対称的に移動を開始できます。つまり、マークアップ、ダウンします。 、中心点から左右に、対称位置もマークされています。たとえば、(3,3)->(4,3)、(3,3)->(2,3)もマークする必要があります。トラバーサルがグリッドの境界に達すると、クリッピングが完了し、バックトラックが実行されます。

コード


public class _方格分割 {
	static int[][] map = new int[7][7];//网格线
	static int[][] v = new int[7][7];//标记当前点是否访问过,即当前位置是否已经剪过
	static int ans = 0;//最终答案
	static int[][] step = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };//上下左右坐标变换

	static void dfs(int x, int y) {
		// 首先判断是否到达边界
		if (x == 0 || y == 0 || x == 6 || y == 6) {
			ans++;
			return;
		}
		// 对称标记已经剪过该位置
		v[x][y] = 1;
		v[6 - x][6 - y] = 1;
		// 依次上下左右剪
		for (int i = 0; i < 4; i++) {
			int newx = x + step[i][0];
			int newy = y + step[i][1];
			// 判断当前位置是否剪过并且没有越界
			if (v[newx][newy] == 0 && newx >= 0 && newx <= 6 && newy >= 0 && newy <= 6) {
				dfs(newx, newy);// 向下一步剪
			}
		}
		// 剪完过后记得回溯
		v[x][y] = 0;
		v[6 - x][6 - y] = 0;
	}

	public static void main(String[] args) {
		dfs(3, 3);// 从(3,3)开始中心对称位置剪
		System.out.println(ans / 4);// 因为中心对称剪的话,每条路线可绕中心点旋转一周,因此一条路线重复了4次,所以要将最后结果/4
	}
}

おすすめ

転載: blog.csdn.net/qq_52360069/article/details/123461726