3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。
给定一个由整数组成的 N × N 矩阵,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。
示例 1:
输入: [[4,3,8,4],
[9,5,1,9],
[2,7,6,2]]
输出: 1
解释:
下面的子矩阵是一个 3 x 3 的幻方:
438
951
276
而这一个不是:
384
519
762
总的来说,在本示例所给定的矩阵中只有一个 3 x 3 的幻方子矩阵。
提示:
1 <= grid.length = grid[0].length <= 10
0 <= grid[i][j] <= 15
解析:
该题目,主要分为两个步骤,一个是将原矩阵,划分为若干个3*3的矩阵,第二步是判断3*3的矩阵是否是幻阵。在划分的时候注意矩阵是否可划分,即行列是否都大于等于3,还要注意最后一个划分起点的位置。判断幻阵时,注意是否有重复元素和大于9的元素,然后只需要判断第一行,第一列,第一个对角线和第二行,第二列即可,不需要所有行列对角线都判断,因为这5个已经涵盖了所有元素。
代码:
//判断是否幻阵
bool isMagicSquares(vector<vector<int>>& subGrid)
{
set<int>sGrid;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
sGrid.insert(sGrid.begin(), subGrid[i][j]);
}
}
//用set判断是否有重复元素和大于9的元素
if (sGrid.size() < 9 || *(--sGrid.end()) > 9)
return false;
if (subGrid[0][0] + subGrid[0][1] + subGrid[0][2] != 15)
return false;
if (subGrid[0][0] + subGrid[1][1] + subGrid[2][2] != 15)
return false;
if (subGrid[0][0] + subGrid[1][0] + subGrid[2][0] != 15)
return false;
if (subGrid[1][0] + subGrid[1][1] + subGrid[1][2] != 15)
return false;
return true;
}
int numMagicSquaresInside(vector<vector<int>>& grid)
{
vector<vector<int>>subGrid(3,vector<int>(3));
int rows = grid.size();
int cols = grid[0].size();
if (rows < 3 || cols < 3)
return 0;
int res = 0;
for (int i = 0; i < rows - 2; i++)
{
for (int j = 0; j < cols - 2; j++)
{
subGrid[0][0] = grid[i][j];
subGrid[0][1] = grid[i][j+1];
subGrid[0][2] = grid[i][j+2];
subGrid[1][0] = grid[i+1][j];
subGrid[1][1] = grid[i+1][j+1];
subGrid[1][2] = grid[i+1][j+2];
subGrid[2][0] = grid[i+2][j];
subGrid[2][1] = grid[i+2][j+1];
subGrid[2][2] = grid[i+2][j+2];
if (isMagicSquares(subGrid))
res++;
}
}
return res;
}
int numMagicSquaresInside(vector<vector<int>>& grid)
{
int row=grid.size();
int col=grid[0].size();
int count=0;
set<int>s;
for(int i=1;i<row-1;i++)
{
for(int j=1;j<col-1;j++)
{
if(grid[i][j]!=5)//幻方中间必须为5
continue;
s.insert(s.begin(),grid[i-1][j-1]);
s.insert(s.begin(),grid[i-1][j]);
s.insert(s.begin(),grid[i-1][j+1]);
s.insert(s.begin(),grid[i][j-1]);
s.insert(s.begin(),grid[i][j]);
s.insert(s.begin(),grid[i][j+1]);
s.insert(s.begin(),grid[i+1][j-1]);
s.insert(s.begin(),grid[i+1][j]);
s.insert(s.begin(),grid[i+1][j+1]);
if(s.size()!=9)//判断是否有重复元素
{
s.clear();
continue;
}
if(*s.begin()!=1)//判断数字为1-9
{
s.clear();
continue;
}
if(*s.end()!=9)
{
s.clear();
continue;
}
s.clear();
if((grid[i][j]+grid[i-1][j-1]+grid[i+1][j+1]==15)
&&(grid[i][j]+grid[i-1][j]+grid[i+1][j]==15)
&&(grid[i][j]+grid[i-1][j+1]+grid[i+1][j-1]==15)
&&(grid[i][j]+grid[i][j-1]+grid[i][j+1]==15)
&&(grid[i-1][j]+grid[i-1][j-1]+grid[i-1][j+1]==15)
&&(grid[i+1][j]+grid[i+1][j-1]+grid[i+1][j+1]==15)
&&(grid[i-1][j-1]+grid[i][j-1]+grid[i+1][j-1]==15)
&&(grid[i-1][j+1]+grid[i][j+1]+grid[i+1][j+1]==15)
)
count++;
}
}
return count;
}