题目描述
小蓝正在和朋友们玩一种新的连连看游戏。在一个 n × m 的矩形网格中,每个格子中都有一个整数,第 i 行第 j 列上的整数为 Ai, j 。玩家需要在这个网格中寻找一对格子 (a, b) − (c, d) 使得这两个格子中的整数 Aa,b 和 Ac,d 相等,且它们的位置满足 |a − c| = |b − d| > 0 。请问在这个 n × m 的矩形网格中有多少对这样的格子满足条件。
输入格式
输入的第一行包含两个正整数 n, m ,用一个空格分隔。
接下来 n 行,第 i 行包含 m 个正整数 Ai,1, Ai,2, · · · , Ai,m ,相邻整数之间使用一个空格分隔。
输出格式
输出一行包含一个整数表示答案。
样例输入
3 2
1 2
2 3
3 2
样例输出
6
样例说明
样例说明
一共有以下 6对格子:(1,2)−(2,1),(2,2)−(3,1),(2,1)−(3,2),(2,1)−(1,2),(3,1)−(2,2),(3,2)−(2,1)。
解题思路
先分析一下题意,题目要求的是:①两个数相等;②坐标满足|a − c| = |b − d| > 0。什么意思呢?就是说要让两个点所在的横坐标之差的绝对值与纵坐标之差绝对值相等。那我们对式子变一下型其实可以发现(以a-c=b-d=k>0来看,a=c+k,b=d+k),要找的数是处于对角线上的。来看一下图
有如图所示的两种情况。
我们以中间那个数为例:分别判断它左上角,右上角,左下角,右下角的数与它是否相等,如果相等的话,那么就增加答案的个数。
但是根据样例说明以及我们的分析其实可以发现,将两个数交换位置其实也算是一组答案。
我们还是举例来看,如果中间那个数和它左上角那个数相等,那么答案就加1,那交换之后的个数是怎么计入的?其实遍历到它左上角那个数的时候,判断它的右下角的数(即中间那个数)的时候,也对答案加1了。
由此我们的思路就是,遍历矩阵当中的每一个数,然后判断它左上角,右上角,左下角,右下角的数是否和它相等即可。
代码实现
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
int ans=0;
int [][]grid=new int[n][m];
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
grid[i][j]=scan.nextInt();
}
}
//一个个检查
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
ans+=check(grid,i,j,n,m);
}
}
System.out.println(ans);
}
private static int check(int[][] grid, int i, int j, int n, int m) {
int count=0;
int value=grid[i][j];
//检查右下角
for(int k=1;i+k<n&&j+k<m;k++) {
if(grid[i+k][j+k]==value)
count++;
}
//检查左下角
for(int k=1;i+k<n&&j-k>=0;k++) {
if(grid[i+k][j-k]==value)
count++;
}
//检查右上角
for(int k=1;i-k>=0&&j+k<m;k++) {
if(grid[i-k][j+k]==value)
count++;
}
//检查左上角
for(int k=1;i-k>=0&&j-k>=0;k++) {
if(grid[i-k][j-k]==value)
count++;
}
return count;
}
}
class Scanner {
private BufferedReader bf;
private StreamTokenizer st;
public Scanner(InputStream inputStream) {
this.bf = new BufferedReader(new InputStreamReader(inputStream));
this.st = new StreamTokenizer(bf);
}
public int nextInt() throws IOException {
st.nextToken();
return (int)st.nval;
}
public String nextLine() throws IOException {
return bf.readLine();
}
}