七月集训---矩阵

目录

题目一:1975. 最大方阵和

解题思路:

代码:

题目二:840. 矩阵中的幻方

解题思路:

代码: 


 

 

题目一:1975. 最大方阵和

问题描述:

给你一个 n x n 的整数方阵 matrix 。你可以执行以下操作 任意次 :

选择 matrix 中 相邻 两个元素,并将它们都 乘以 -1 。
如果两个元素有 公共边 ,那么它们就是 相邻 的。

你的目的是 最大化 方阵元素的和。请你在执行以上操作之后,返回方阵的 最大 和。

解题思路:

首先需要知道一个前提就是,矩阵中的任意的两个数都可以通过操作之后变换成正数,无论它们的位置如何(具体方法是选定两个负数,在它们之间连一条线,通过线不断将两个负号往中间靠拢,直至一条线都变成正数)。所以,如果负数的个数为偶数,那么所有的负数可以变成正数,反之,则会有一个负数落单。

同样地,如果矩阵之中有0,那么所有的负数都可以变成正数,0和任意负数连线。

因此我们的思路就变成了:

①判断矩阵中是否有0,有就计算所有元素的绝对值之和

②计算负数的个数,如果为偶数,就计算所有元素的绝对值之和

如果为奇数,那么把所有元素绝对值之和减去 元素中绝对值最小的,这里有点贪心的思想。

代码:

long long maxMatrixSum(int** matrix, int matrixSize, int* matrixColSize){
  int r, c = matrixSize;
  int i, j;
  long long res = 0;

  for(i=0; i<r; i++)    //计算所有元素绝对值之和
  {
      for(j=0; j<c; j++)
      {
          res +=abs(matrix[i][j]);
      }
  }
  long long max_ = 0;  
  int cnt = 0;   //计数器
  int how = 0;

  for(i=0; i<r; i++)
  {
    for(j=0; j<c; j++)
    {
      if(matrix[i][j] == 0)    //如果有0,则直接输出res
      {
          how = 1;
      }
      if(matrix[i][j] < 0)         //计算负数的个数
       {    
          cnt++;
      }
    }
  }
  for(i=0; i<r; i++)            //绝对值之和减去绝对值最小的元素
    for(j=0; j<c;j++)
      {
        max_ = fmax(max_, res-abs(matrix[i][j]) );
      }

  if(how == 1)
    return res;
  else
  {
    if(cnt % 2 == 0)
      return res;
    else
      return max_;
  }
}

                     


题目二:840. 矩阵中的幻方

3 x 3 的幻方是一个填充有 从 1 到 9  的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。

给定一个由整数组成的row x col 的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

解题思路:

①以任意一个元素为起点,判断3 x 3的行和和列和是否相等

 ②判断主副对角线是否相等

 ③判断每行每列以及对角线出现的数字在1-9之间,并且两两不重复(用哈希表计算每个数字出现的个数)

因为条件多,所以代码量也会有点多,但是思路总体不会很难

                

代码: 

int Is_Magic(int **grid, int x, int y)
{
    int sum = grid[x][y] + grid[x][y+1] + grid[x][y+2];
    for(int i=0;i<3;++i){
           //统计行和
        if(sum != grid[x+i][y]+grid[x+i][y+1]+grid[x+i][y+2])
          return 0;
          //统计列和
        if(sum != grid[x][y+i]+grid[x+1][y+i]+grid[x+2][y+i])
          return 0;
      }

  //判断对角线
    if(sum != grid[x][y]+grid[x+1][y+1]+grid[x+2][y+2])
      return 0;
    if(sum != grid[x][y+2] +grid[x+1][y+1]+grid[x+2][y])
      return 0;

  //判断1-9是否重复出现以及是否数字不在1-9范围内
  int hash[10];
  memset(hash,0,sizeof(int)*10);
  for(int i=0; i<3; i++)
    for(int j=0; j<3; j++)
    {
      if(grid[x+i][y+j] <1 || grid[x+i][y+j] > 9)
        return 0;
      ++hash[grid[x+i][y+j]];

    }
  for(int i=1; i<=9; i++)
    if(hash[i] != 1)
      return 0;

  return 1;
    
}

int numMagicSquaresInside(int** grid, int gridSize, int* gridColSize){
  int r = gridSize;
  int c = gridColSize[0];
  int i, j;
  int res = 0;

  if(r<3 || c<3)
    return 0;
//遍历矩阵
  for(i=0; i<r-2; i++)
    for(j=0; j<c-2; j++)
      if(Is_Magic(grid, i, j))
        res+= 1;

  return res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值