二维数组的最大联通子数组
团队人员:
赵子鸣、白要朋
工作照片:
主要思路:
将一个二维数组中的非负数块分出来,一次标上记号,在一次求这些模块的最短权值路径,以和最大的模块为基础,看加上其他模块相对最小路径权值来说是否值得(和是否大于0),值得便加上,否则不加,最后遍历完这些模块之后,便可以得到最大联通子数组
合作过程:先一起分析问题的逻辑思路,将其在数学上转为模块化,在用java实现,在设计思路时有过几个想法,比如每一行先找最大子数组,在按列相加权值,但是有bug,所以这个思路不成立,最后确定非负数模块化的思路。
体会以及解决冲突:这个题目主要的问题在于算法的设计,起初没什么思路,后通过查阅网上相关算法,获得两个思路,开始有分歧,后来通过找缺陷(bug)来判断算法的合理性,最后通过举反例说明第一种思路的缺陷型,最终采用第二种思路,主要java代码如下所示。
package Shi2; import java.util.Scanner; public class Shi0 { public static int[][] gai(int a[][],int nn){ boolean ll=false; for(int i=0;i<5;i++){ for(int y=0;y<5;y++){ if(a[i][y]==0){ a[i][y]=nn; ll=true; break; } } if(ll==true) break; } for(int ii=0;ii<25;ii++){ for(int i=0;i<5;i++){ for(int y=0;y<5;y++){ a=zhouwei(a,i,y,nn); } } } return a; } public static int[][] zhouwei(int a[][],int i,int y,int nn){ if(a[i][y]==nn){ if(i==0&&y==0){ if(a[0][1]==0) a[0][1]=nn; if(a[1][0]==0) a[1][0]=nn; } else if(i==4&&y==4){ if(a[4][3]==0) a[4][3]=nn; if(a[3][4]==0) a[3][4]=nn; } else if(i==0&&y==4){ if(a[0][3]==0) a[0][3]=nn; if(a[4][1]==0) a[4][1]=nn; } else if(i==4&&y==0){ if(a[4][1]==0) a[4][1]=nn; if(a[3][0]==0) a[3][0]=nn; } else if(i==0){ if(a[0][y+1]==0) a[0][y+1]=nn; if(a[0][y-1]==0) a[0][y-1]=nn; if(a[1][y]==0) a[1][y]=nn; } else if(y==0){ if(a[i+1][0]==0) a[i+1][0]=nn; if(a[i-1][0]==0) a[i-1][0]=nn; if(a[i][1]==0) a[i][1]=nn; } else if(i==4){ if(a[4][y+1]==0) a[4][y+1]=nn; if(a[4][y-1]==0) a[4][y-1]=nn; if(a[3][y]==0) a[3][y]=nn; } else if(y==4){ if(a[i+1][4]==0) a[i+1][4]=nn; if(a[i-1][4]==0) a[i-1][4]=nn; if(a[i][3]==0) a[i][3]=nn; } else { if(a[i][y-1]==0) a[i][y-1]=nn; if(a[i][y+1]==0) a[i][y+1]=nn; if(a[i+1][y]==0) a[i+1][y]=nn; if(a[i-1][y]==0) a[i-1][y]=nn; } } return a; } public static void main(String[] args) { //int a[][]=new int [5][5]; int a[][]={{1,2,3,-1,-1},{1,2,-1,-1,-1},{-1,-1,-1,-1,-1},{1,1,1,1,1},{-1,-1,-1,-1,-1}}; int b[][]=new int [5][5]; System.out.println("输入5行5列"); Scanner input=new Scanner(System.in); for(int i=0;i<5;i++){ for(int y=0;y<5;y++){ System.out.print(a[i][y]+" "); } System.out.println(); } System.out.println(); System.out.println(); for(int i=0;i<5;i++){ for(int y=0;y<5;y++){ //a[i][y]=input.nextInt(); if(a[i][y]>=0) b[i][y]=0; else b[i][y]=-1; } } for(int t=0;t<25;t++){ b=gai(b,t); } for(int i=0;i<5;i++){ for(int y=0;y<5;y++){ System.out.print(b[i][y]+" "); } System.out.println(); } input.close(); } }
截图(生成非负整数模块):
在这个模块的基础上,利用数据结构中的弗洛伊德算法求出以最大和的模块与其他模块的最小权值路径,判断是否值得相加,最后得出结果。