OJ-POJ1021-暴力

这篇博客探讨了如何判断两个图形是否通过旋转、平移或翻转形成相同图形的问题。作者提出了一种暴力求解方法,即列举所有可能并逐一比较,并分享了自己在解决这个问题时的理解和错误分析,包括找群的正确和错误方法。最终,博主提供了通过AC的代码,其中findClusters方法被指出是错误的,而findClusters2为正确实现。

这题网上有代码量很少的解法,可惜我看不明白。

先不管题目,讨论如何判断两个图形相同(旋转,平移,翻转)?

就是如下8个图形中,任选出两个,要得出它们是两个相同的图形:


我的方法特土特暴力:列出8种,然后分别比较。。。

回到题目,自己的理解是(对左右两个板):

a,找到群。要求左右,群数相同,群中点数相同
b,群中点数相同的,一定有一对一相同的形状

分析过程:

1,找群,这里犯了一个错误,不能只用点,应该从上到下从左到右遍历板

2,群按照群中点数排序,每个点数中的群数应该是一样的。

3,对每个点数中的群,左右必须有一一对应的关系。

贴一份AC代码,findClusters方法就是错误的找群方法,正确的是findClusters2

package poj10x;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

/*
 * 	status : Accept
 * 	Memory 	Time
 * 	3772K	204MS
 * 	
 */

/*
 * 	text file encoding : utf8
 * 	大意:
 * 		1,意思非常绕口
 * 		2,先说操作吧:
 * 			a,删除连续的一行或者一列
 * 			b,删除最后一块的胜利
 * 			c,左右两个板,要求是左边赢的操作,在右边同样赢
 * 		3,自己的理解(以下说辞都是对左右两个板):
 * 			a,找到群。要求左右,群数相同,群中点数相同
 * 			b,群中点数相同的,一定有一对一相同的形状
 * 	输入:
 * 		2(测试数)
 * 		8 5 11(X,Y,点个数)
 * 		0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 5 2 4 4
 * 		0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4
 * 		8 5 11
 * 		0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 6 1 4 4
 * 		0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4
 * 	输出:
 * 		YES(左右相同)
 * 		NO(左右不相同)
 */

public class P1021 {
	static int bigX, bigY;
	static Point p[], p_other[], p_this[];
	static Cluster cluster_save;
	static Cluster[] arrayOfCluster;
	static ClusterMap[] clusterMap_this, clusterMap_other;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int numOfTest = scanner.nextInt();
		while(numOfTest -- > 0) {
			bigX = scanner.nextInt();
			bigY = scanner.nextInt();
			p = new Point[scanner.nextInt()];
			p_other = new Point[p.length];
			p_this = new Point[p.length];
			for (int indexOfPoint = 0; indexOfPoint < p.length; indexOfPoint ++) {
				p[indexOfPoint] = new Point(scanner.nextInt(), scanner.nextInt());
				p_this[indexOfPoint] = p[indexOfPoint];
			}
			arrayOfCluster = findClusters2();
			Arrays.sort(arrayOfCluster);
			clusterMap_this = getClusterMap();
			for (int indexOfPoint = 0; indexOfPoint < p.length; indexOfPoint ++) {
				p[indexOfPoint] = new Point(scanner.nextInt(), scanner.nextInt());
				p_other[indexOfPoint] = p[indexOfPoint];
			}
			arrayOfCluster = findClusters2();
			Arrays.sort(arrayOfCluster);
			clusterMap_other = getClusterMap();
			
			if (clusterMap_this.length != clusterMap_other.length) {
				System.out.println("NO");
				continue;
			}
			boolean isAllFormRight = true;
			for (int indexOfMap = 0; indexOfMap < clusterMap_this.length; indexOfMap ++) {
				isAllFormRight &= clusterMap_this[indexOfMap].data.length == clusterMap_other[indexOfMap].data.length;
				isAllFormRight &= clusterMap_this[indexOfMap].data[0].length == clusterMap_other[indexOfMap].data[0].length;
				if (!isAllFormRight) {
					break;
				}
			}
			if (!isAllFormRight) {
				System.out.println("NO");
				continue;
			}
			boolean returnMatch = getReturn();
			if (returnMatch) {
				System.out.println("YES");
			} else {
				System.out.println("NO");
			}
		}
		scanner.close();
	}
	
	static Cluster[] findClusters2() {
		ArrayList<Cluster> arrayListCluster = new ArrayList<Cluster>();
		int isFored[][] = new int[bigX][bigY];
		for (int x = 0; x < bigX; x ++) {
			Arrays.fill(isFored[x], -1);
		}
		for (int pIndex = 0; pIndex < p.length; pIndex ++) {
			isFored[p[pIndex].x][p[pIndex].y] = pIndex;
		}
		Cluster cluster = null;
		for (int y = 0; y < bigY; y ++) {
			for (int x = 0; x < bigX; x ++) {
				if (isFored[x][y] >= 0) {
					cluster = new Cluster();
					// cluster.pointIndex.add(isFored[x][y]);
					addToPointIndex(cluster.pointIndex, x, y, isFored);
					arrayListCluster.add(cluster);
				}
			}
		}
		Cluster[] clusters = new Cluster[arrayListCluster.size()];
		for (int index = 0; index < clusters.length; index ++) {
			clusters[index] = arrayListCluster.get(index);
		}
		return clusters;
	}
	public static void addToPointIndex(Set<Integer> pointIndex, int x, int y, int[][] isFored) {
		if (x < 0 || x >= bigX || y < 0 || y >= bigY) {
			return;
		}
		if (isFored[x][y] >= 0 && ! pointIndex.contains(isFored[x][y])) {
			pointIndex.add(isFored[x][y]);
			isFored[x][y] = -2;
			addToPointIndex(pointIndex, x+1, y, isFored);
			addToPointIndex(pointIndex, x-1, y, isFored);
			addToPointIndex(pointIndex, x, y-1, isFored);
			addToPointIndex(pointIndex, x, y+1, isFored);
		}
	}
	static boolean getReturn() {
		boolean returnMatch = true;
		for (int indexOfMap = 0; indexOfMap < clusterMap_this.length; indexOfMap ++) {
			int[][] data_this = clusterMap_this[indexOfMap].data;
			int[][] data_other = clusterMap_other[indexOfMap].data;
			int sizeOfCluster = data_this[0].length, lengthOfData = data_this.length;
			if(sizeOfCluster == 1 || sizeOfCluster == 2) {
				continue;
			}
			Point[][] point_this = new Point[lengthOfData][sizeOfCluster];
			Point[][] point_other = new Point[lengthOfData][sizeOfCluster];
			for (int indexOfLen = 0; indexOfLen < lengthOfData; indexOfLen ++) {
				for (int indexOfSize = 0; indexOfSize < sizeOfCluster; indexOfSize ++) {
					Point this_point = p_this[data_this[indexOfLen][indexOfSize]];
					Point other_point = p_other[data_other[indexOfLen][indexOfSize]];
					point_this[indexOfLen][indexOfSize] = new Point(this_point.x, this_point.y);
					point_other[indexOfLen][indexOfSize] = new Point(other_point.x, other_point.y);
				}
				moveTo00(point_other[indexOfLen]);
				moveTo00(point_this[indexOfLen]);
			}
			final int len = lengthOfData;
			boolean map[] = new boolean[len];
			Arrays.fill(map, false);
			boolean isTrue1 = true;
			for (int index1 = 0; index1 < len; index1 ++) {
				boolean isTrue2 = false;
				for (int index2 = 0; index2 < len; index2 ++) {
					if (map[index2]) {
						continue;
					}
					if (! exitOneMatch(point_this[index1], point_other[index2])) {
						continue;
					}
					map[index2] = true;
					isTrue2 |= true;
					break;
				}
				if (! isTrue2) {
					isTrue1 &= false;
				}
			}
			returnMatch &= isTrue1;
		}
		return returnMatch;
	}
	static boolean exitOneMatch(Point[] arr1, Point[] arr2) {
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		axialSymmetry(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		clockwist90(arr1);
		if (compareTwoPointArray(arr1, arr2)) {
			return true;
		}
		return false;
	}
	static void moveTo00 (Point[] arr) {
		int min_x_1 = Integer.MAX_VALUE, min_y_1 = Integer.MAX_VALUE;
		for (int arr1Index = 0; arr1Index < arr.length; arr1Index ++) {
			if (arr[arr1Index].x < min_x_1) {
				min_x_1 = arr[arr1Index].x;
			}
			if (arr[arr1Index].y < min_y_1) {
				min_y_1 = arr[arr1Index].y;
			}
		}
		for (int arr1Index = 0; arr1Index < arr.length; arr1Index ++) {
			arr[arr1Index].x -= min_x_1;
			arr[arr1Index].y -= min_y_1;
		}
	}
	static void clockwist90(Point[] arr) {
		int min_x_1 = Integer.MAX_VALUE, min_y_1 = Integer.MAX_VALUE;
		for (int arr1Index = 0; arr1Index < arr.length; arr1Index ++) {
			int x = arr[arr1Index].x;
			int y = arr[arr1Index].y;
			arr[arr1Index].x = y;
			arr[arr1Index].y = -x;
			if (arr[arr1Index].x < min_x_1) {
				min_x_1 = arr[arr1Index].x;
			}
			if (arr[arr1Index].y < min_y_1) {
				min_y_1 = arr[arr1Index].y;
			}
		}
		for (int arr1Index = 0; arr1Index < arr.length; arr1Index ++) {
			arr[arr1Index].x -= min_x_1;
			arr[arr1Index].y -= min_y_1;
		}
	}
	static void axialSymmetry(Point[] arr) {
		int max_x = Integer.MIN_VALUE;
		for (int index = 0; index < arr.length; index ++) {
			if (arr[index].x > max_x) {
				max_x = arr[index].x;
			}
		}
		for (int index = 0; index < arr.length; index ++) {
			int x = arr[index].x;
			arr[index].x = max_x - x;
		}
	}
	static boolean compareTwoPointArray(Point[] arr1, Point[] arr2) {
		if (arr1.length != arr2.length) {
			return false;
		}
		final int len = arr1.length;
		boolean[] match = new boolean[len];
		Arrays.fill(match, false);
		boolean returnAllMatch = true;
		for (int index1 = 0; index1 < len; index1 ++) {
			boolean findOneIn2Match = false;
			for (int index2 = 0; index2 < len; index2 ++) {
				if (match[index2]) {
					continue;
				}
				if (!arr2[index2].equals(arr1[index1])) {
					continue;
				}
				match[index2] = true;
				findOneIn2Match |= true;
				break;
			}
			if (!findOneIn2Match) {
				returnAllMatch &= false;
				break;
			}
		}
		return returnAllMatch;
	}
	static ClusterMap[] getClusterMap() {
		int finalLengthOfClusterMap = 0;
		for (int indexOfArray = 0; indexOfArray < arrayOfCluster.length; indexOfArray ++) {
			int sizeOfCluster = arrayOfCluster[indexOfArray].pointIndex.size();
			int lengthOfData = 1;
			for (int indexOfIndex = indexOfArray + 1; indexOfIndex < arrayOfCluster.length; indexOfIndex ++) {
				if (arrayOfCluster[indexOfIndex].pointIndex.size() == sizeOfCluster) {
					lengthOfData ++;
				} else {
					break;
				}
			}
			finalLengthOfClusterMap ++;
			indexOfArray += lengthOfData - 1;
		}
		ClusterMap[] arrayOfClusterMap = new ClusterMap[finalLengthOfClusterMap];
		int lengthOfClustermap = 0;
		for (int indexOfArray = 0; indexOfArray < arrayOfCluster.length; indexOfArray ++) {
			int sizeOfCluster = arrayOfCluster[indexOfArray].pointIndex.size();
			int lengthOfData = 1;
			for (int indexOfIndex = indexOfArray + 1; indexOfIndex < arrayOfCluster.length; indexOfIndex ++) {
				if (arrayOfCluster[indexOfIndex].pointIndex.size() == sizeOfCluster) {
					lengthOfData ++;
				} else {
					break;
				}
			}
			ClusterMap clusterMap = new ClusterMap(sizeOfCluster, lengthOfData);
			arrayOfClusterMap[lengthOfClustermap] = clusterMap;
			lengthOfClustermap ++;
			int[][] data = clusterMap.data;
			for (int indexOfData = 0; indexOfData < lengthOfData; indexOfData ++) {
				int realIndex = indexOfArray + indexOfData;
				Set<Integer> set = arrayOfCluster[realIndex].pointIndex;
				int secondIndex = 0;
				for(int setDate : set) {
					data[indexOfData][secondIndex] = setDate;
					secondIndex ++;
				}
			}
			indexOfArray += lengthOfData - 1;
		}
		return arrayOfClusterMap;
	}
	static Cluster[] findClusters() {
		List<Cluster> listOfCluster = new ArrayList<Cluster>();
		for (int indexOfPoint = 0; indexOfPoint < p.length; indexOfPoint ++) {
			if ( isExitsInListOfCluster(listOfCluster, indexOfPoint) ){
				continue;
			}
			if ( isExitContiguityInListOfCluster(listOfCluster, indexOfPoint) ) {
				cluster_save.pointIndex.add(indexOfPoint);
				continue;
			}
			Cluster newCluster = new Cluster();
			newCluster.pointIndex.add(indexOfPoint);
			listOfCluster.add(newCluster);
		}
		Cluster[] arrayOfCluster = new Cluster[listOfCluster.size()];
		for (int indexOfList = 0; indexOfList < listOfCluster.size(); indexOfList ++) {
			arrayOfCluster[indexOfList] = listOfCluster.get(indexOfList);
		}
		return arrayOfCluster;
	}
	static boolean isExitContiguityInListOfCluster(List<Cluster> listOfCluster, int indexOfPoint) {
		boolean isExits = false;
		for (int indexOfList = 0; indexOfList < listOfCluster.size(); indexOfList ++) {
			boolean isExitsInList = listOfCluster.get(indexOfList).isExitContiguity(indexOfPoint);
			if(isExitsInList) {
				cluster_save = listOfCluster.get(indexOfList);
			}
			isExits |= isExitsInList;
		}
		return isExits;
	}
	static boolean isExitsInListOfCluster(List<Cluster> listOfCluster, int indexOfPoint) {
		boolean isExits = false;
		for (int indexOfList = 0; indexOfList < listOfCluster.size(); indexOfList ++) {
			isExits |= listOfCluster.get(indexOfList).isExitsInThis(indexOfPoint);
		}
		return isExits;
	}
	static class Point {
		int x;
		int y;
		public Point() {
		}
		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
		public boolean equals(Point o) {
			return this.x == o.x && this.y == o.y;
		}
		public String toString() {
			return x+" "+y;
		}
 	}
	static class Cluster implements Comparable<Cluster>{
		Set<Integer> pointIndex = new HashSet<Integer>();
		public boolean isExitsInThis(int index) {
			return pointIndex.contains(index);
		}
		public boolean isExitContiguity(int index) {
			boolean isExit = false;
			for(int setIndex : pointIndex) {
				isExit |= (Math.abs(p[setIndex].x - p[index].x) + Math.abs(p[setIndex].y - p[index].y)) == 1;
			}
			return isExit;
		}
		@Override
		public int compareTo(Cluster o) {
			return this.pointIndex.size() - o.pointIndex.size();
		}
	}
	static class ClusterMap {
		int sizeOfCluster;
		int data[][];
		public ClusterMap(int sizeOfCluster, int lengthOfData) {
			this.sizeOfCluster = sizeOfCluster;
			data = new int[lengthOfData][sizeOfCluster];
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值