有一个01矩阵,通过改变某些位置的数字(0变成1或1变成0),使矩阵上下左右对称。
思路:假设矩阵是n行m列的,int[][] arr = new int[n][m],若矩阵上下左右都对称,对于矩阵中的某个元素arr[i][j]来说,应该和与它对称的位置上的元素arr[i][ m - 1 - j],arr[n -1 -i][j]都相等,而arr[i][ m - 1 - j],arr[n -1 -i][j]又都与arr[n - 1 - i][m - 1 -j]对称(不清楚就画一下矩阵),所以这四个元素都应该相等,即arr[i][j] = arr[i][ m - 1 - j] = arr[n -1 -i][j] = arr[n - 1 - i][m - 1 -j]。一般情况下,只要统计这四个元素中0和1的个数,其中较小的个数就是要改变的次数。对于矩阵为奇数行或奇数列的情况,中间行(或中间列)要特殊考虑,因为中间行只要左右对称,中间列只要上下对称,所以只要考虑处于对称位置上的两个元素是否相等,相等不用就改变,不等只需改变一次。对于既处于中间行又处于中间列的元素(只有一个),不用改变。
public class SymmetricTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n;
int m;
int count_sum = 0;
n = scan.nextInt();
m = scan.nextInt();
int[][] arr = new int[n][m];
int change = 0; //记录需要改变的次数
for (int i = 0; i < n; i ++){
for (int j = 0; j < m; j++){
arr[i][j] = scan.nextInt();
}
}
for (int i = 0; i < (n + 1) / 2;i++){
for (int j = 0; j < (m + 1) / 2;j++){
int count_1 = 0;
if (i != (n - 1 - i) && j != (m - 1 - j) ){
count_1 = arr[i][j] + arr[i][ m - 1 - j] + arr[n -1 -i][j] + arr[n - 1 - i][m - 1 -j];
change = (count_1 <= (4 - count_1)) ? count_1 : (4 - count_1);
}else if (i != (n - 1 - i) && j == (m - 1 - j)){
change = (arr[i][j] + arr[n -1 -i][j]) % 2;
}else if (i == (n - 1 - i) && j != (m - 1 - j) ){
change = (arr[i][j] + arr[i][ m - 1 - j]) % 2;
}else if (i == (n - 1 - i) && j == (m - 1 - j)){
change = 0;
}
count_sum += change;
}
}
System.out.println(count_sum);
}
}