题4:边长为1的最大子方阵优化预处理
对每个位置上为1的元素找右边下边有多少个1
1 1 1 0
1 1 0 1
1 1 0 1
0 1 1 13,3 2,4 1,0 0,0
2,2 1,3 0,0 1,3
2,1 1,2 0,0 1,2
0,0 3,1 2,1 1,1
(右,下)//算上自身[3],[3] 2,[4]
[2], 2 1, 3
只需要看这四个数就可以确定一个正方形//输出右下1个数的矩阵
private static void print(int[][][] rec,int N){for(int i=0;i<N;i++){for(int j=0;j<N;j++){System.out.print(rec[i][j][0]+","+rec[i][j][1]+"\t");}System.out.println();}
}
//全局变量
int[][][]res;//保存1右下个数的数组//生成右边和下边的1的数量的数组
private static void generateHelpRec(int[][] A){
int N=A.length;
res=new int[N][N][2];//最后一行int row=N-1;//初始化最下面一层for(int j=N-1;j>=0;j--){int value=A[row][j];if(value==1){if(j==N-1){rec[row][j][0]=1;}//右侧连接1的个数,最底层else{rec[row][j][0]=rec[row][j+1][0]+1;}res[row][j][1]=1;}}row--;for(int i=row;i>=0;i--){for(int j=N-1;j>=0;j--){int value=A[i][j];if(value==1){if(j==N-1)rec[i][j][0]=-1;elserec[i][j][0]=1=rec[i][j+1][0]+1;res[i][j][1]=res[i][j][1]+1;//向下连接的个数}}}return
}//检查四条边是否正确
private static boolean check(int i,int j,int n){//左上角那个点往右数的1的数目要≥n//左上角那个点往下数的1的数目要≥n//右上角那个点往下数的1的数目要≥n//左下角那个点往右数的1的数目要≥nif(rec[i][j][0]>=n&&rec[i][j][1]>=n&&rec[i][j+n-1][1]>=n&&rec[i+n-1][j][0]>=n)return true;return false;
}
private static int solve(int[][] A){int N=A.length;int n=N;while(n>0){for(int i=0;i<N;i++){l3;if(i+n>N)break;//越界for(int j=0;j<N;j++){if(j+n>N)break;//越界//检查四个边if(check(i,j,n))return n;}}}
}//这种从底层往上求的方式类似于动态规划里的打表法