题目:输入一个N*M的矩阵,元素为1表示有一个士兵,元素为0表示没有士兵,如果一个士兵的上下左右相邻的士兵可以归为一个队伍,同一个队伍的士兵越多,队伍越强大,现在可以随意移动一个士兵,求移动之后可以得到的最大队伍的士兵数:
比如输入:
4 4
1 0 0 1
1 1 0 1
0 0 0 1
1 1 1 1
输出10。
思路:和岛问题很像,我当时没想出来,看了别人的思路后面补了一下,基本是按照下面来的。
public static int res=0;
public static int tag=1;//岛标签
public static HashMap<Integer,Integer> map;
public static int tmpsum=0;//每个岛的最大士兵数量
//对岛上的元素添加标签并且统计个数
public static void process(int[][] matrix,int row,int col){
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(matrix[i][j]==1)
{
tag++;//这个岛的标签
tmpsum=0;
infect(matrix,i,j,row,col);//尝试对周围进行感染
System.out.println("tag: "+tag+"sum: "+tmpsum);
map.put(tag, tmpsum);//每个岛的标签和士兵数量保存在map里面
}
}
}
}
public static void process2(int[][] matrix ,int row,int col){
HashSet<Integer> set;
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(matrix[i][j]==0){
int tmp=0;
set=new HashSet<>();
int[] sizhou=new int[4];//四周
//如果超过边界或者是0,就不用统计
sizhou[0]=i==0||matrix[i-1][j]==0?-1:matrix[i-1][j];//上面的标签
sizhou[1]=i==row-1||matrix[i+1][j]==0?-1:matrix[i+1][j];//上下左右
sizhou[2]=j==0||matrix[i][j-1]==0?-1:matrix[i][j-1];
sizhou[3]=j==col-1||matrix[i][j+1]==0?-1:matrix[i][j+1];
for(int m=0;m<4;m++){//使用set去重
if(sizhou[m]!=-1){
if(!set.contains(sizhou[m])){
set.add(sizhou[m]);
tmp+=map.get(sizhou[m]);//累加
}
}
}
if(set.size()==map.size()){
int tmpres=tmp;
res=Math.max(res,tmpres);
}else{
int tmpres=tmp+1;
res=Math.max(res,tmpres);
}
}
}
}
}
public static void infect(int[][] matrix,int i,int j,int row,int col){
if(i<0||i>=row||j<0||j>=col||matrix[i][j]!=1)
return ;
matrix[i][j]=tag;
tmpsum++;
infect(matrix,i+1,j,row,col);
infect(matrix,i-1,j,row,col);
infect(matrix,i,j+1,row,col);
infect(matrix,i,j-1,row,col);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
map=new HashMap<>();
while(sc.hasNext()){
int n=sc.nextInt();
int m =sc.nextInt();
sc.nextLine();
int[][] matrix=new int[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
matrix[i][j]= sc.nextInt();
}
sc.nextLine();
}
process(matrix,n,m);
process2(matrix,n,m);
System.out.println(res);
}
}