java矩阵基础算法题,在线等

zgycsmb 2020-04-12 08:27:56
办公室内,规定二个员工之间的位置不能相邻,前后左右均为相邻,
现给出一个办公地区座位分布:一个m*n的矩阵,每个元素为一个字符, '.'代表有位置,可以办公, '*'代表没有电源,不能办公,请根据输入(输入格式下面的例子中有,计算可容多少员工同时办公,
比如 输入 这串 [ [*,.,*,*,.],[*,.,*,*,*],[*,.,*,*,.] ] 须输出4,
请问,此题用java应该如何写呢,在线等,thanks.
...全文
536 17 打赏 收藏 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
YangjulongTrue 2020-04-18
  • 打赏
  • 举报
回复
引用 2 楼 nayi_224 的回复:
        char [][]ok=new char[3][3];
ok[0]=new char[]{'*','*','*','.','.'};
ok[1]=new char[]{'*','*','*','.','*'};
ok[2]=new char[]{'*','*','*','*','*'};

这种是要输出1还是2?
我重新写了个你看看


package test;

import java.util.ArrayList;
import java.util.List;

class pa{
public pa(int x,int y) {
this.y=y;
this.x=x;
}
public int x;
public int y;
}
public class StudentDamo{
static int max=0;
public static void main(String[] args) throws Exception{
char [][]ok=new char[3][3];
ok[0]=new char[]{'*','*','*','.','.'};
ok[1]=new char[]{'*','*','*','.','*'};
ok[2]=new char[]{'*','*','*','*','*'};
searchX(ok,0,0,0);
System.out.println(max);
}
public static void searchX(char[][]arr,int emrow,int emclo,int size) {
if(emrow>=arr.length) {//防止行过界
max=Math.max(max, size);
return ;
}

for (int i = emrow; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
if(i==emrow&&j<emclo) continue;
if(arr[i][j]=='.') {
max=Math.max(max, size+1);
List<pa> list=search(arr,i,j);
if(j==arr[0].length-1)//当前是最后一个就从头开始
searchX(arr,i+1,0,size+1);
else
searchX(arr,i,j+1,size+1);
for (pa pa : list) {
arr[pa.x][pa.y]='.';//恢复原来的状态
}
}

}
}

}
//返回我需要重置的点
public static List<pa> search(char[][]arr,int emrow,int emclo) {
List<pa> list=new ArrayList<pa>();
//只用判断下和右 我是一边过的 没有考虑最优解
if(emrow==arr.length-1&&emclo==arr[0].length-1) //右下角 不用管
return list;
if(emrow==arr.length-1) {//是最后一行把 右面的 人 kill 了
if(arr[emrow][emclo+1]=='.')
list.add(new pa(emrow, emclo+1));
arr[emrow][emclo+1]='*';
} else if(emclo==arr[0].length-1) {//同理 最后一列 把下面的kill
if(arr[emrow+1][emclo]=='.')
list.add(new pa(emrow+1, emclo));
arr[emrow+1][emclo]='*';
} else {
if(arr[emrow+1][emclo]=='.')
list.add(new pa(emrow+1, emclo));
if(arr[emrow][emclo+1]=='.')
list.add(new pa(emrow, emclo+1));
arr[emrow][emclo+1]='*';//同上
arr[emrow+1][emclo]='*';
}
return list;
}
}
qq_39936465 2020-04-17
  • 打赏
  • 举报
回复
引用 12 楼 ywfpclt 的回复:
[quote=引用 11 楼 qq_39936465 的回复:] 我的sublist的计算时间度是n的立方,请理解一下算法。你的递归方法时间复杂度你自己算算是多少。
你别上火,理论讨论一下,我是java业余新手,完全是爱好,看见你用的位移和位与计算方法还是大开眼界 不嫌弃的话可以多多交流,我的QQ3462907 另外你的程序真的有问题,就拿下面的这个6*6矩阵例子计算一下 而我的基本是秒完,当然,矩阵再大点我的也会等很久,再再高点我的也好像会溢出[/quote] 你只是举一个例子来说,并不能说明你的程序更优化,因为当n趋向无穷大时递归方法负担要求更大,请参考程序的复杂度和时间度的推算。所以你说你的程序更优化我完全get不到你的点。 我不知道你为什么会溢出,我用我的程序执行你的数组时完全没有问题。我在程序中添加时间计算。最后得到13和9秒
ywfpclt 2020-04-17
  • 打赏
  • 举报
回复
上面的是8*8共64-9=55个可用位置的算法 而8*8=64个可用位置矩阵的运行结果是:(用时太长了,应该还可以改进)
---所有排列方法---
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
------32------
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
* . * . * . * . 
. * . * . * . * 
------32------
最大可用位置数:32
8*8矩阵64个可用位置总执行时间:576084毫秒
ywfpclt 2020-04-17
  • 打赏
  • 举报
回复
为什么不能编辑,有个小错误(统计数忘了置0),改正下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class Demo {
	static int maxCon = 0;// 统计最大可用位置数

	public static void main(String[] args) {
		char[][] ok = new char[8][8];
		ok[0] = new char[] { '.', '.', '.', '.', '.', '*', '.', '.' };
		ok[1] = new char[] { '.', '.', '.', '.', '.', '.', '.', '.' };
		ok[2] = new char[] { '.', '*', '.', '.', '.', '.', '*', '.' };
		ok[3] = new char[] { '.', '.', '.', '.', '.', '*', '.', '.' };
		ok[4] = new char[] { '.', '.', '*', '.', '.', '*', '.', '.' };
		ok[5] = new char[] { '.', '.', '.', '.', '.', '.', '*', '.' };
		ok[6] = new char[] { '*', '.', '.', '*', '.', '.', '.', '.' };
		ok[7] = new char[] { '.', '.', '.', '.', '.', '.', '.', '.' };
		long start = new Date().getTime();
		search(ok);
		System.out.println("最大可用位置数:" + maxCon);
		System.out.println("8*8矩阵64个可用位置总执行时间:" + (new Date().getTime() - start) + "毫秒");
	}

	public static void search(char[][] arr) {
		// 第一轮计算
		List<char[][]> listA = new ArrayList<>();
		search(reverseArray(arr), listA);
		// 第二轮计算
		List<char[][]> listB = new ArrayList<>();
		maxCon = 0;// 最大可用位置数置0
		for (int i = 0; i < listA.size(); i++) {
			search(reverseArray(listA.get(i)), listB);
		}
		printList(listB);// 打印,如果不需要打印,可去掉
	}

	public static void printList(List<char[][]> list) {
		// 打印所有位置法
		System.out.println("---所有排列方法---");
		for (int s = 0; s < list.size(); s++) {
			for (int i = 0; i < list.get(s).length; i++) {
				for (int j = 0; j < list.get(s)[i].length; j++) {
					System.out.print(list.get(s)[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println("------" + maxCon + "------");
		}
	}

	public static void search(char[][] arr, List<char[][]> list) {
		int[] index = side(arr);
		if (index[0] == -1) {
			int con = 0;// 统计可用位置数
			for (int i = 0; i < arr.length; i++) {
				for (int j = 0; j < arr[i].length; j++) {
					if (arr[i][j] == '.') {
						con++;
					}
				}
			}
			if (maxCon < con) {
				list.clear();
				maxCon = con;
				list.add(arr);
			} else if (maxCon == con) {
				list.add(arr);
			}
		} else {
			// 复制数组
			char[][] arrL = new char[arr.length][];
			char[][] arrR = new char[arr.length][];
			for (int i = 0; i < arrL.length; i++) {
				arrL[i] = Arrays.copyOf(arr[i], arr[i].length);
				arrR[i] = Arrays.copyOf(arr[i], arr[i].length);
			}
			// 去掉右边位置递归方法
			arrL[index[0]][index[1] + 1] = '*';
			search(arrL, list);
			// 去掉左边位置递归方法
			arrR[index[0]][index[1]] = '*';
			if (index[1] + 2 < arrR[index[0]].length) {
				arrR[index[0]][index[1] + 2] = '*';
			}
			search(arrR, list);
		}
	}

	// 数组翻转
	public static char[][] reverseArray(char[][] arr) {
		int maxLength = 0;
		for (int i = 0; i < arr.length; i++) {
			if (maxLength < arr[i].length) {
				maxLength = arr[i].length;
			}
		}
		char[][] arrReverse = new char[maxLength][arr.length];
		for (int i = 0; i < arrReverse.length; i++) {
			for (int j = 0; j < arrReverse[i].length; j++) {
				if (i < arr[j].length) {
					arrReverse[i][j] = arr[j][i];
				} else {
					arrReverse[i][j] = '*';
				}
			}
		}
		return arrReverse;
	}

	// 判断是否有左右相邻可用位置并返回索引
	public static int[] side(char[][] arr) {
		int[] out = { -1, -1 };// -1为没有相邻可用位置
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (arr[i][j] == '.') {// 判断该位置是否可用
					if (out[0] == -1 && j + 1 < arr[i].length && arr[i][j + 1] == '.') {
						out[0] = i;// 获取第一个有相邻位置的Y索引
						out[1] = j;// 获取第一个有相邻位置的X索引
					}
				}
			}
		}
		return out;
	}
}
以8*8矩阵为例:
		ok[0] = new char[] { '.', '.', '.', '.', '.', '*', '.', '.' };
		ok[1] = new char[] { '.', '.', '.', '.', '.', '.', '.', '.' };
		ok[2] = new char[] { '.', '*', '.', '.', '.', '.', '*', '.' };
		ok[3] = new char[] { '.', '.', '.', '.', '.', '*', '.', '.' };
		ok[4] = new char[] { '.', '.', '*', '.', '.', '*', '.', '.' };
		ok[5] = new char[] { '.', '.', '.', '.', '.', '.', '*', '.' };
		ok[6] = new char[] { '*', '.', '.', '*', '.', '.', '.', '.' };
		ok[7] = new char[] { '.', '.', '.', '.', '.', '.', '.', '.' };
两次运行结果:
---所有排列方法---
. * . * . * . * 
* . * . * . * . 
. * . * . * * * 
* . * . * * * . 
. * * * . * . * 
* . * . * . * . 
* * * * . * . * 
. * . * * . * . 
------27------
. * . * . * . * 
* . * . * . * . 
. * . * . * * * 
* . * . * * * . 
. * * * . * . * 
* . * . * . * . 
* * * * . * . * 
. * * . * . * . 
------27------
. * . * . * . * 
* . * . * . * . 
. * . * . * * * 
* . * . * * * . 
. * * * . * . * 
* . * . * . * . 
* * * * . * . * 
* . * . * . * . 
------27------
最大可用位置数:27
8*8矩阵64个可用位置总执行时间:24581毫秒
第二次:8*8矩阵64个可用位置总执行时间:25100毫秒
ywfpclt 2020-04-17
  • 打赏
  • 举报
回复
我的问题解决了,改进了一下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class Demo {
	static int maxCon = 0;// 统计最大可用位置数

	public static void main(String[] args) {
		char[][] ok = new char[8][7];
		ok[0] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[1] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[2] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[3] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[4] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[5] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[6] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[7] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		long start = new Date().getTime();
		search(ok);
		System.out.println("最大可用位置数:" + maxCon);
		System.out.println("8*7矩阵56个可用位置总执行时间:" + (new Date().getTime() - start) + "毫秒");
	}

	public static void search(char[][] arr) {
		List<char[][]> listA = new ArrayList<>();
		search(reverseArray(arr), listA);
		List<char[][]> listB = new ArrayList<>();
		for (int i = 0; i < listA.size(); i++) {
			search(reverseArray(listA.get(i)), listB);
		}
		printList(listB);// 打印,如果不需要打印,可去掉
	}

	public static void printList(List<char[][]> list) {
		// 打印所有位置法
		System.out.println("---所有排列方法---");
		for (int s = 0; s < list.size(); s++) {
			for (int i = 0; i < list.get(s).length; i++) {
				for (int j = 0; j < list.get(s)[i].length; j++) {
					System.out.print(list.get(s)[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println("------" + maxCon + "------");
		}
	}

	public static void search(char[][] arr, List<char[][]> list) {
		int[] index = side(arr);
		if (index[0] == -1) {
			int con = 0;// 统计最大可用位置数
			for (int i = 0; i < arr.length; i++) {
				for (int j = 0; j < arr[i].length; j++) {
					if (arr[i][j] == '.') {
						con++;
					}
				}
			}
			if (maxCon > con) {
				return;
			} else if (maxCon < con) {
				list.clear();
				maxCon = con;
			}
			list.add(arr);
		} else {
			// 复制数组
			char[][] arrL = new char[arr.length][];
			char[][] arrR = new char[arr.length][];
			for (int i = 0; i < arrL.length; i++) {
				arrL[i] = Arrays.copyOf(arr[i], arr[i].length);
				arrR[i] = Arrays.copyOf(arr[i], arr[i].length);
			}
			// 去掉右边位置递归方法
			arrL[index[0]][index[1] + 1] = '*';
			search(arrL, list);
			// 去掉左边位置递归方法
			arrR[index[0]][index[1]] = '*';
			if (index[1] + 2 < arrR[index[0]].length) {
				arrR[index[0]][index[1] + 2] = '*';
			}
			search(arrR, list);
		}
	}

	// 数组翻转
	public static char[][] reverseArray(char[][] arr) {
		int maxLength = 0;
		for (int i = 0; i < arr.length; i++) {
			if (maxLength < arr[i].length) {
				maxLength = arr[i].length;
			}
		}
		char[][] arrReverse = new char[maxLength][arr.length];
		for (int i = 0; i < arrReverse.length; i++) {
			for (int j = 0; j < arrReverse[i].length; j++) {
				if (i < arr[j].length) {
					arrReverse[i][j] = arr[j][i];
				} else {
					arrReverse[i][j] = '*';
				}
			}
		}
		return arrReverse;
	}

	// 判断是否有左右相邻可用位置并返回索引
	public static int[] side(char[][] arr) {
		int[] out = { -1, -1 };// -1为没有相邻可用位置
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (arr[i][j] == '.') {// 判断该位置是否可用
					if (out[0] == -1 && j + 1 < arr[i].length && arr[i][j + 1] == '.') {
						out[0] = i;// 获取第一个有相邻位置的Y索引
						out[1] = j;// 获取第一个有相邻位置的X索引
					}
				}
			}
		}
		return out;
	}
}
以上代码以“8*7矩阵56个可用位置”为例运行了一下:
		char[][] ok = new char[8][7];
		ok[0] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[1] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[2] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[3] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[4] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[5] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[6] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
		ok[7] = new char[] { '.', '.', '.', '.', '.', '.', '.' };
运行结果为:
---所有排列方法---
. * . * . * . 
* . * . * . * 
. * . * . * . 
* . * . * . * 
. * . * . * . 
* . * . * . * 
. * . * . * . 
* . * . * . * 
------28------
* . * . * . * 
. * . * . * . 
* . * . * . * 
. * . * . * . 
* . * . * . * 
. * . * . * . 
* . * . * . * 
. * . * . * . 
------28------
最大可用位置数:28
8*7矩阵56个可用位置总执行时间:41547毫秒
你的应该完全无法运行了
qq_39936465 2020-04-16
  • 打赏
  • 举报
回复
引用 9 楼 ywfpclt 的回复:
[quote=引用 8 楼 qq_39936465 的回复:] [/code]
你的问题不只这点,主要问题还在你的subList存放了大量的List对象,而且这里面的List对象里也有对象 我测试了一下,在楼主给定题目中,6个可用位置的条件下你的subList长度是64,如果是全部15个可用位置的条件下,你的subList长度可达32768,如果再多点呢?150个呢? 而我的就要小很多了,搞了一天搞出来了,基本思路和6楼说的差不多,不过又有变化,6楼考虑不周: 先将位置图翻转(即横纵坐标对换) 找到第一个左右相邻位置index(不看上下方): 如果找不到: 将此位置图添加到位置图集合List。 如果找到采取两种方法: 一种是去掉index右边的位置,然后递归重复; 另一种是去掉index右边的位置(如果右边有可用位置的话也顺便去掉,然后递归重复; 将集合List中的所有位置图逐个翻转(即横纵坐标对换),清空List,然后再来一遍找左右相邻位置方法。 最后从集合List中找到最多位置的位置图,便是答案(这里参考了你的方法)。 我的代码还有改进的地方,就是将位置图的二维数组换成你的Position对象集合,有时间再改,具体代码如下: [/quote] 你考虑问题太片面了,如果座位遇到梅花型的情况呢,座位越多将产生梅花型的情况越复杂,还有连块梅花型的情况,你的算法时间度会几何倍增长,不会比我的小多少。而我排序只是比较list的size大小,不是里面的内容。
ywfpclt 2020-04-16
  • 打赏
  • 举报
回复
引用 11 楼 qq_39936465 的回复:
我的sublist的计算时间度是n的立方,请理解一下算法。你的递归方法时间复杂度你自己算算是多少。
你别上火,理论讨论一下,我是java业余新手,完全是爱好,看见你用的位移和位与计算方法还是大开眼界 不嫌弃的话可以多多交流,我的QQ3462907 另外你的程序真的有问题,就拿下面的这个6*6矩阵例子计算一下
char[][] ok = new char[6][6];
        ok[0]=new char[]{'.','.','*','*','.','*'};
        ok[1]=new char[]{'.','.','.','.','.','.'};
        ok[2]=new char[]{'.','.','*','*','.','*'};
        ok[3]=new char[]{'.','.','*','*','.','*'};
        ok[4]=new char[]{'.','.','.','.','.','.'};
        ok[5]=new char[]{'.','.','*','*','.','*'};
你的运行后过一会才会出来溢出异常,
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.ArrayList.grow(Unknown Source)
	at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
	at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
	at java.util.ArrayList.add(Unknown Source)
	at Demo1.allsub(Demo1.java:58)
	at Demo1.main(Demo1.java:25)
而我的基本是秒完,当然,矩阵再大点我的也会等很久,再再高点我的也好像会溢出
qq_39936465 2020-04-16
  • 打赏
  • 举报
回复
我的sublist的计算时间度是n的立方,请理解一下算法。你的递归方法时间复杂度你自己算算是多少。
ywfpclt 2020-04-15
  • 打赏
  • 举报
回复
引用 8 楼 qq_39936465 的回复:
[/code]
你的问题不只这点,主要问题还在你的subList存放了大量的List对象,而且这里面的List对象里也有对象 我测试了一下,在楼主给定题目中,6个可用位置的条件下你的subList长度是64,如果是全部15个可用位置的条件下,你的subList长度可达32768,如果再多点呢?150个呢? 而我的就要小很多了,搞了一天搞出来了,基本思路和6楼说的差不多,不过又有变化,6楼考虑不周: 先将位置图翻转(即横纵坐标对换) 找到第一个左右相邻位置index(不看上下方): 如果找不到: 将此位置图添加到位置图集合List。 如果找到采取两种方法: 一种是去掉index右边的位置,然后递归重复; 另一种是去掉index右边的位置(如果右边有可用位置的话也顺便去掉,然后递归重复; 将集合List中的所有位置图逐个翻转(即横纵坐标对换),清空List,然后再来一遍找左右相邻位置方法。 最后从集合List中找到最多位置的位置图,便是答案(这里参考了你的方法)。 我的代码还有改进的地方,就是将位置图的二维数组换成你的Position对象集合,有时间再改,具体代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Demo {
	public static void main(String[] args) {
		char[][] ok = new char[3][3];
		ok[0] = new char[] { '*', '.', '*', '.', '.' };
		ok[1] = new char[] { '.', '.', '*', '.', '*' };
		ok[2] = new char[] { '*', '*', '*', '*', '*' };
		System.out.println(search(ok));
	}

	public static int search(char[][] arr) {
		List<char[][]> list = new ArrayList<>();
		search(reverseArray(arr), list);
		int s = list.size();
		for (int i = 0; i < s; i++) {
			search(reverseArray(list.get(0)), list);
			list.remove(0);
		}
		int maxCon = 0;// 统计最大可用位置数
		for (s = 0; s < list.size(); s++) {
			int con = 0;// 统计最大可用位置数
			for (int i = 0; i < list.get(s).length; i++) {
				for (int j = 0; j < list.get(s)[i].length; j++) {
					if (list.get(s)[i][j] == '.') {
						con++;
					}
				}
			}
			if (maxCon < con) {
				maxCon = con;
				for (int i = 0; i < s; i++) {
					list.remove(0);
				}
				s = 0;
			} else if (maxCon > con) {
				list.remove(s);
				s--;
			}
		}
		printList(list);// 打印,如果不需要打印,可去掉
		return maxCon;
	}

	public static void printList(List<char[][]> list) {
		// 打印所有位置法
		for (int s = 0; s < list.size(); s++) {
			int con = 0;
			for (int i = 0; i < list.get(s).length; i++) {
				for (int j = 0; j < list.get(s)[i].length; j++) {
					System.out.print(list.get(s)[i][j] + " ");
					if (list.get(s)[i][j] == '.') {
						con++;
					}
				}
				System.out.println();
			}
			System.out.println("----------");
		}
	}

	public static void search(char[][] arr, List<char[][]> list) {
		int[] index = side(arr);
		if (index[0] == -1) {
			list.add(arr);
		} else {
			// 复制数组
			char[][] arrL = new char[arr.length][];
			char[][] arrR = new char[arr.length][];
			for (int i = 0; i < arrL.length; i++) {
				arrL[i] = Arrays.copyOf(arr[i], arr[i].length);
				arrR[i] = Arrays.copyOf(arr[i], arr[i].length);
			}
			// 去掉右边位置递归方法
			arrL[index[0]][index[1] + 1] = '*';
			search(arrL, list);
			// 去掉左边位置递归方法
			arrR[index[0]][index[1]] = '*';
			if (index[1] + 2 < arrR[index[0]].length) {
				arrR[index[0]][index[1] + 2] = '*';
			}
			search(arrR, list);
		}
	}

	// 数组翻转
	public static char[][] reverseArray(char[][] arr) {
		int maxLength = 0;
		for (int i = 0; i < arr.length; i++) {
			if (maxLength < arr[i].length) {
				maxLength = arr[i].length;
			}
		}
		char[][] arrReverse = new char[maxLength][arr.length];
		for (int i = 0; i < arrReverse.length; i++) {
			for (int j = 0; j < arrReverse[i].length; j++) {
				if (i < arr[j].length) {
					arrReverse[i][j] = arr[j][i];
				} else {
					arrReverse[i][j] = '*';
				}
			}
		}
		return arrReverse;
	}

	// 判断是否有左右相邻可用位置并返回索引
	public static int[] side(char[][] arr) {
		int[] out = { -1, -1 };// -1为没有相邻可用位置
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (arr[i][j] == '.') {// 判断该位置是否可用
					if (out[0] == -1 && j + 1 < arr[i].length && arr[i][j + 1] == '.') {
						out[0] = i;// 获取第一个有相邻位置的Y索引
						out[1] = j;// 获取第一个有相邻位置的X索引
					}
				}
			}
		}
		return out;
	}
}
qq_39936465 2020-04-15
  • 打赏
  • 举报
回复
按上面说的修正了一下程序

public class Test8 {
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int max=0;
        char[][] c= {{'*','.','*','*','.'},{'*','.','*','*','*'},{'*','.','*','*','.'} }  ;
        //将所有可以做人的位子放入list中
        List<Position> list=new ArrayList<Position>();
        for (int i=0;i<c.length;i++) {
            for(int j=0;j<c[0].length;j++) {
                if(c[i][j]=='.') {
                    list.add(new Position(i, j));
                }
            }
        }
        //取该list所有子列集合
        List<List<Position>> subList=allsub(list);
        //对该集合按size大小从大到小排列
        Collections.sort(subList, new Comparator<List<Position>>() {
			@Override
			public int compare(List<Position> o1, List<Position> o2) {
				// TODO Auto-generated method stub
				if(o1.size()>o2.size())return -1;
				else if(o1.size()==o2.size())return 0;
				else return 1;
			}
		});
         //第一个符合条件的就是最大值。
        for(List<Position> l:subList) {
            if(check(l)) {
            	 System.out.println(l.size());
            	 break;
            }
        }
    }
     
    static boolean check(List<Position> list) {
        for(int i=0;i<list.size();i++) {
            for(int j=i+1;j<list.size();j++) {
                if(list.get(j).side(list.get(i))) {
                    return false;
                }
            }
        }
        return true;
    }
     
    static List<List<Position>> allsub(List<Position> list){
        List<List<Position>> subList=new ArrayList<>();
        for(int i=1;i<Math.pow(2,list.size());i++) {
            int temp=i;
            List<Position> sub=new ArrayList<>();
            for(int j=0;j<list.size();j++) {
                if((temp&1)==1) {
                    sub.add(list.get(j));
                }
                temp>>=1;
            }
            subList.add(sub);
        }
        return subList;
    }
}
qq_39936465 2020-04-15
  • 打赏
  • 举报
回复
引用 6 楼 ywfpclt 的回复:
4楼的我看懂了,是把所有的排列方法全部列出来,然后把有相邻位置的排列方法去掉,剩下的取最大值,这样做保证了正确性,但是我感觉很耗资源,尤其是位置够多的话,运行应该会很慢,我觉得应该有更简单点的方法 这里我想到一个,还没验证不知道正确不正确,等我写好后再发出来 我的思路是:找到第一个左右相邻位置(不看上下方),找到前如果发现有一个位置不与左右相邻,则去掉下方位置。 找到后采取两种方法,一种是去掉左边的位置,另一种是去掉右边的位置 然后在这两种方法中分别去掉右边和下边的位置,然后遍历后面的位置(不考虑左右相邻),并去掉其下方的位置 继续在两种方法中分别找下一个左右相邻位置,重复上面的方法,直到没有相邻位置为止 最后这些方法全部找到后(如果相邻位置多的话,这些方法应该非常多,2的N次方之多,但是比4楼的应该少很多了),找出最大座位数的方法便是答案了
不一定要全部找,你可以先把子集安size大小从大到小排序,第一个条件成立的就可以得出结论。
ywfpclt 2020-04-15
  • 打赏
  • 举报
回复
4楼的我看懂了,是把所有的排列方法全部列出来,然后把有相邻位置的排列方法去掉,剩下的取最大值,这样做保证了正确性,但是我感觉很耗资源,尤其是位置够多的话,运行应该会很慢,我觉得应该有更简单点的方法 这里我想到一个,还没验证不知道正确不正确,等我写好后再发出来 我的思路是:找到第一个左右相邻位置(不看上下方),找到前如果发现有一个位置不与左右相邻,则去掉下方位置。 找到后采取两种方法,一种是去掉左边的位置,另一种是去掉右边的位置 然后在这两种方法中分别去掉右边和下边的位置,然后遍历后面的位置(不考虑左右相邻),并去掉其下方的位置 继续在两种方法中分别找下一个左右相邻位置,重复上面的方法,直到没有相邻位置为止 最后这些方法全部找到后(如果相邻位置多的话,这些方法应该非常多,2的N次方之多,但是比4楼的应该少很多了),找出最大座位数的方法便是答案了
ywfpclt 2020-04-14
  • 打赏
  • 举报
回复
参考了1楼的方法:
public class Demo {
	public static void main(String[] args) throws Exception {
		char[][] ok = new char[3][3];
		ok[0] = new char[] { '*', '.', '*', '*', '.' };
		ok[1] = new char[] { '*', '.', '*', '*', '*' };
		ok[2] = new char[] { '*', '.', '*', '*', '.' };
		System.out.println(search(ok));
	}

	public static int search(char[][] arr) {
		// maxSize:从上下左右最大可用位置数,从最大数4开始依次去掉相邻位置有可用位置的位置
		for (int maxSize = 4; maxSize > 0; maxSize--) {
			for (int i = 0; i < arr.length; i++) {
				for (int j = 0; j < arr[i].length; j++) {
					if (arr[i][j] == '.') {// 判断该位置是否可用
						int size = 0;// 定义上下左右相邻可用位置数
						if (j > 0 && arr[i][j - 1] == '.') {
							size++;// 判断左邻位置是否可用
						}
						if (j < arr[i].length - 1 && arr[i][j + 1] == '.') {
							size++;// 右邻
						}
						if (i > 0 && arr[i - 1][j] == '.') {
							size++;// 上邻
						}
						if (i < arr.length - 1 && arr[i + 1][j] == '.') {
							size++;// 下邻
						}
						if (size == maxSize) {// 判断相邻可用位置数是否为最maxSize值
							arr[i][j] = '*';// 将该位置设置为不可用
						}
					}
				}
			}
		}
		// 统计可用位置数
		int size = 0;
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (arr[i][j] == '.') {
					size++;
				}
			}
		}
		return size;
	}
}
ywfpclt 2020-04-14
  • 打赏
  • 举报
回复
楼上的正确,我的是错误的,请楼主无视
qq_39936465 2020-04-14
  • 打赏
  • 举报
回复
引用 楼主 zgycsmb 的回复:
办公室内,规定二个员工之间的位置不能相邻,前后左右均为相邻, 现给出一个办公地区座位分布:一个m*n的矩阵,每个元素为一个字符, '.'代表有位置,可以办公, '*'代表没有电源,不能办公,请根据输入(输入格式下面的例子中有,计算可容多少员工同时办公, 比如 输入 这串 [ [*,.,*,*,.],[*,.,*,*,*],[*,.,*,*,.] ] 须输出4, 请问,此题用java应该如何写呢,在线等,thanks.

public class Position {
	private int x;
	private int y;
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public Position(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	//判断相邻与否
	boolean side(Position p) {
		if(x==p.getX()&&(Math.abs(y-p.getY())==1))return true;
		if(y==p.getY()&&(Math.abs(x-p.getX())==1))return true;
		return false;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return getX()+":"+getY();
	}
}

public class Test8 {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int max=0;
		char[][] c= {{'*','.','*','*','.'},{'*','.','*','*','*'},{'*','.','*','*','.'} }  ;
		//将所有可以做人的位子放入list中
		List<Position> list=new ArrayList<Position>();
		for (int i=0;i<c.length;i++) {
			for(int j=0;j<c[0].length;j++) {
				if(c[i][j]=='.') {
					list.add(new Position(i, j));
				}
			}
		}
		//取该list所有子列集合
		List<List<Position>> subList=allsub(list);
		
		//取符合条件的子集的最大值
		for(List<Position> l:subList) {
			if(check(l)) {
				if(l.size()>max)max=l.size();
			}
		}
		System.out.println(max);
	}
	
	static boolean check(List<Position> list) {
		for(int i=0;i<list.size();i++) {
			for(int j=i+1;j<list.size();j++) {
				if(list.get(j).side(list.get(i))) {
					return false;
				}
			}
		}
		return true;
	}
	
	static List<List<Position>> allsub(List<Position> list){
		List<List<Position>> subList=new ArrayList<>();
	    for(int i=0;i<Math.pow(2,list.size());i++) {
	    	int temp=i;
	    	List<Position> sub=new ArrayList<>();
	    	for(int j=0;j<list.size();j++) {
	    		if((temp&1)==1) {
	    			sub.add(list.get(j));
	    		}
	    	    temp>>=1;
	    	}
	    	subList.add(sub);
	    }
	    return subList;
	}
}

YangjulongTrue 2020-04-13
  • 打赏
  • 举报
回复

package test;


public class StudentDamo{
public static void main(String[] args) throws Exception{
char [][]ok=new char[3][3];
ok[0]=new char[]{'*','.','*','*','.'};
ok[1]=new char[]{'*','.','*','*','*'};
ok[2]=new char[]{'*','.','*','*','.'};
int sum=0;
for (int i = 0; i < ok.length; i++) {
for (int j = 0; j < ok[0].length; j++) {
if(ok[i][j]=='.') {
search(ok, i, j);
sum++;
}
}
}
System.out.println(sum);
}
public static void search(char[][]arr,int emrow,int emclo) {
//只用判断下和右 我是一边过的 没有考虑最优解
if(emrow==arr.length-1&&emclo==arr[0].length-1) //右下角 不用管
return;
if(emrow==arr.length-1) {//是最后一行把 右面的 人 kill 了
arr[emrow][emclo+1]='*';
} else if(emclo==arr[0].length-1) {//同理 最后一列 把下面的kill
arr[emrow+1][emclo]='*';
} else {
arr[emrow][emclo+1]='*';//同上
arr[emrow+1][emclo]='*';
}
}
}

nayi_224 2020-04-13
  • 打赏
  • 举报
回复
        char [][]ok=new char[3][3];
        ok[0]=new char[]{'*','*','*','.','.'};
        ok[1]=new char[]{'*','*','*','.','*'};
        ok[2]=new char[]{'*','*','*','*','*'};
这种是要输出1还是2?

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧