码迷,mamicode.com
首页 > 其他好文 > 详细

蓝桥杯_PREV_4剪格子

时间:2015-05-23 16:59:20      阅读:334      评论:0      收藏:0      [点我收藏+]

标签:搜索   回溯   dfs   

题目:

历届试题 剪格子  
时间限制:1.0s   内存限制:256.0MB
      
问题描述

如下图所示,3 x 3 的格子中填写了一些整数。

+--*--+--+
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+

我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。

本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。

如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。

如果无法分割,则输出 0。

输入格式

程序先读入两个整数 m n 用空格分割 (m,n<10)。

表示表格的宽度和高度。

接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。

输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入1
3 3
10 1 52
20 30 1
1 2 3
样例输出1
3
样例输入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
样例输出2
10
解题思路:

首先求出所有节点和的一半sum,从左上角那个点一次向后进行回溯+剪枝搜索,如遇到所经过结点和等于sum,则将深度deep加入优先级队列(使用优先级队列可以在最后直接peek得出最小深度)。

回溯采用dfs的方法,剪枝条件有

(1)所经过结点和大于sum

(2)所经过结点和等于sum

(3)结点x,y坐标超出矩阵边界

(4)当前结点之前已经到达过,即b[x][y] == true

代码如下:

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class Main {

	// 总和的一半
	static int num;
	// 行数
	static int hang;
	// 列数
	static int lie;
	// 存放数据
	static int[][] mix;
	// 记录某个结点是否在当前路径下已经被访问,false表示未访问,true表示已访问
	static boolean[][] b;
	// 当前路径所经过结点和
	static int sum = 0;
	// 优先队列
	static Queue<Integer> queue = new PriorityQueue<Integer>();
	
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		lie = sc.nextInt();
		hang = sc.nextInt();
		mix = new int[hang][lie];
		b = new boolean[hang][lie];
		int temp = 0;
		for (int a = 0; a < hang; a++) {
			for (int b = 0; b < lie; b++) {
				mix[a][b] = sc.nextInt();
				temp += mix[a][b];
			}
		}
		num = temp >> 1;
		sc.close();
		
		dfs(0, 0, 1);
		
		System.out.println(queue.peek() == null ? 0 : queue.peek());
	}

	/**
	 * 回溯矩阵所有结点
	 * @param x
	 * @param y
	 * @param deep
	 */
	private static void dfs(int x, int y, int deep) {

		if (x < 0 || x >= hang || y < 0 || y >= lie || b[x][y]) {
			return;
		}
		if ((sum + mix[x][y]) > num) {
			return;
		}
		if ((sum + mix[x][y]) == num) {
			queue.add(deep);
			return;
		}
		
		sum += mix[x][y];
		b[x][y] = true;
		
		dfs(x - 1, y, deep + 1);
		dfs(x, y - 1, deep + 1);
		dfs(x + 1, y, deep + 1);
		dfs(x, y + 1, deep + 1);
		
		sum -= mix[x][y];
		b[x][y] = false;
	}
	
}


蓝桥杯_PREV_4剪格子

标签:搜索   回溯   dfs   

原文地址:http://blog.csdn.net/u011333588/article/details/45934799

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!