OJ-POJ1022-DFS

这题就是一个四维在唬人,看一个两维的简化版:

给7个二维单位正方形。现在想把它们粘起来,然后放到一个大正方形容器上。

7

1 3 2 0 4

2 1 0 0 0

3 5 1 0 0

4 0 0 1 0

5 0 3 0 0 

6 0 0 4 7

7 0 0 6 0

每行输入的格式是[ID][右边][左边][上边][下边]

将7个小块粘好,得到图形

AAAAA

分析过程如下:

1,判断有没有规则错误:

举例:已知1号的信息是:3号在其右边,如果3号的信息是:左边不是1号,那么出规则错误。

2,从1号进入,深搜,粘上所有能够粘上的。记录:lenOfGrow数组,mapOfParts布尔数组

lenOfGrow表示的是以1号为原点,向4个方向的最大延伸

mapOfParts表示下标对应ID的小块有没有粘上

3,判断有没有全部粘完。

4,出错,输出Inconsistent,否则输出容器面积。

就这么简单!!!!!

在写代码的时候需要注意,小块的ID与小块的输入顺序无关。

贴一份AC代码:

package poj10x;

import java.util.Arrays;
import java.util.Scanner;

/*
 * 	status : Accept
 * 	Memory 	Time
 * 	5260K	235MS
 */

/*
 * 	大意:
 * 		1,不要去想四维的东西是什么!
 * 		2,每个“小块”,各个边长都是单位长度
 * 		3,操作过程就是:将各个小块粘起来
 * 	输入:
  		1(测试用例数)
  		9(小块数目)
  		1 2 3 4 5 6 7 8 9(第一个数字是ID,后面8个数字是粘的规则)
		2 0 1 0 0 0 0 0 0
		3 1 0 0 0 0 0 0 0
		4 0 0 0 1 0 0 0 0
		5 0 0 1 0 0 0 0 0
		6 0 0 0 0 0 1 0 0
		7 0 0 0 0 1 0 0 0
		8 0 0 0 0 0 0 0 1
		9 0 0 0 0 0 0 1 0
 * 	输出:
 * 		1,规则有矛盾		输出:Inconsistent
 * 		2,没有粘完		输出:Inconsistent
 * 		3,用一个容器装下粘结好的大块。输出容器体积。
 */

public class P1022 {
	static int numOfParts, dataOfParts[][];		// 记录输入信息
	static boolean mapOfParts[];				// 记录小块有没有被粘进来
	static int[] lenOfGrow = new int[8];		// 以0号为原点,向8个方向的最大延伸
	static int[] location = new int[4];		// 记录深搜过程中,当前点的位置
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int numOfTest = scanner.nextInt();
		while (numOfTest -- > 0) {
			numOfParts = scanner.nextInt();
			dataOfParts = new int[numOfParts][9];
			for (int indexOfParts = 0; indexOfParts < numOfParts; indexOfParts ++) {
				for (int indexOfData = 0; indexOfData < 9; indexOfData ++) {
					dataOfParts[indexOfParts][indexOfData] = scanner.nextInt();
				}
			}
			// 判断有没有规则矛盾
			if (! judgeSymmetric()) {
				System.out.println("Inconsistent");
				continue;
			}
			mapOfParts = new boolean[numOfParts];
			Arrays.fill(mapOfParts, false);
			Arrays.fill(lenOfGrow, 0);
			Arrays.fill(location, 0);
			// 从0号开始深搜小块
			searchAllContiguousStarts0(0);
			// 判断有没有全部粘完
			if (judgeOneComonent()) {
				System.out.println(calculateVolume());
			} else {
				System.out.println("Inconsistent");
			}
		}
		scanner.close();
	}
	static int calculateVolume() {
		int volume = 1;
		for (int index = 0; index < 4; index ++) {
			volume *= (lenOfGrow[2*index + 0] + lenOfGrow[2*index + 1] + 1);
		}
		return volume;
	}
	static int getIndexInLocation(int index) {
		return (index-1) >> 1;
	}
	// 判断有没有粘完
	static boolean judgeOneComonent() {
		boolean isOne = true;
		for (int index = 0; index < mapOfParts.length; index ++) {
			isOne &= mapOfParts[index];
		}
		return isOne;
	}
	// 从0号开始进行深搜
	static void searchAllContiguousStarts0(int thisPart) {
		if (mapOfParts[thisPart]) {
			return;
		}
		mapOfParts[thisPart] = true;
		for (int indexOfLocation = 0; indexOfLocation < 4; indexOfLocation ++) {
			if (location[indexOfLocation] > 0) {
				if (lenOfGrow[2*indexOfLocation] < location[indexOfLocation]) {
					lenOfGrow[2*indexOfLocation] = location[indexOfLocation];
				}
			} else if (location[indexOfLocation] < 0) {
				if (lenOfGrow[2*indexOfLocation + 1] < -location[indexOfLocation]) {
					lenOfGrow[2*indexOfLocation + 1] = -location[indexOfLocation];
				}
			}
		}
		for (int indexOfData = 1; indexOfData < dataOfParts[0].length; indexOfData ++) {
			if (dataOfParts[thisPart][indexOfData] == 0) {
				continue;
			}
			int correspond = dataOfParts[thisPart][indexOfData];
			int indexOfParts2 = 0;
			for (; indexOfParts2 < dataOfParts.length; indexOfParts2 ++) {
				if (dataOfParts[indexOfParts2][0] == correspond) {
					break;
				}
			}
			if ((indexOfData & 0x1) == 1) {
				location[getIndexInLocation(indexOfData)] ++;
			} else {
				location[getIndexInLocation(indexOfData)] --;
			}
			searchAllContiguousStarts0(indexOfParts2);
			if ((indexOfData & 0x1) == 1) {
				location[getIndexInLocation(indexOfData)] --;
			} else {
				location[getIndexInLocation(indexOfData)] ++;
			}
		}
	}
	// 判断有没有规则矛盾
	static boolean judgeSymmetric() {
		if (dataOfParts == null || dataOfParts[0].length != 9) {
			return false;
		}
		for (int indexOfParts = 0; indexOfParts < dataOfParts.length; indexOfParts ++) {
			for (int indexOfData = 1; indexOfData < dataOfParts[0].length; indexOfData ++) {
				if (dataOfParts[indexOfParts][indexOfData] == 0) {
					continue;
				}
				int correspond = dataOfParts[indexOfParts][indexOfData];
				int indexOfParts2 = 0;
				boolean isFound = false;
				for (; indexOfParts2 < dataOfParts.length; indexOfParts2 ++) {
					if (dataOfParts[indexOfParts2][0] == correspond) {
						isFound = true;
						break;
					}
				}
				if (! isFound) {
					return false;
				}
				int indexOfData2 = indexOfData;
				if ((indexOfData2 & 0x1) == 1) {
					indexOfData2 ++;
				} else {
					indexOfData2 --;
				}
				if (dataOfParts[indexOfParts2][indexOfData2] != dataOfParts[indexOfParts][0]) {
					return false;
				}
			}
		}
		return true;
	}
}


SDUT-OJ(Software Development University of Tsinghua Online Judge)是一个在线编程平台,提供给清华大学软件学院的学生和爱好者练习和解决算法问题的环境,其中包括各种计算机科学题目,包括数据结构、算法、图形等。对于"最小生成树"(Minimum Spanning Tree, MST)问题,它是图论中的经典问题,目标是从一个加权无向图中找到一棵包含所有顶点的树,使得树的所有边的权重之和最小。 在C语言中,最常见的是使用Prim算法或Kruskal算法来求解最小生成树。Prim算法从一个顶点开始,逐步添加与当前生成树相连且权重最小的边,直到所有顶点都被包含;而Kruskal算法则是从小到大对所有边排序,每次选取没有形成环的新边加入到树中。 如果你想了解如何用C语言实现这些算法,这里简单概括一下: - 通常使用优先队列(堆)来存储边和它们的权重,以便快速查找最小值。 - 从任意一个顶点开始,遍历与其相邻的边,若新边不形成环,就更新树,并将新边加入优先队列。 - Kruskal算法: - 先将所有的边按照权重升序排序。 - 创建一个空的最小生成树,然后依次取出排序后的边,如果这条边连接的两个顶点不在同一个连通分量,则将其添加到树中。 如果你需要更详细的代码示例,或者有具体的问题想了解(比如如何处理环、如何实现优先队列等),请告诉我,我会为你提供相应的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值