【7月アルゴリズム】day11配列

トピック、まれに行う必要があります

1975. 正方行列の最大和

タイトル説明:

nxn の整数の正方行列が与えられます。次の操作は何度でも実行できます。

行列の 2 つの隣接する要素を選択し、両方を -1 で乗算します。
2 つの要素がエッジを共有している場合、それらは隣接しています。

目標は、正方行列の要素の合計を最大化することです。上記の操作を実行した後、正方行列の最大和を返してください。

アイデア:

負の数が偶数の場合、すべての負の数を正の数に変換する必要があり、すべての数を合計すると答えが得られます (負の数は正の数になります)。

負の数の数が奇数の場合、累積されたすべての数から、配列全体の最小値の 2 倍を減算する必要があります (負の数が正の数になった後)。

実際、私はもともとベクトルを使用してすべての要素を格納していましたが、

アイデアを書いているときに、配列全体の最小値を決定するために 1 つの値を使用するだけでよいことがわかりました。. .

class Solution {
public:
    long long maxMatrixSum(vector<vector<int>>& matrix) {
        int r = matrix.size();
        int c = matrix[0].size();
        long long sum = 0;
        int minv = 110000000;
        int cntneg = 0;
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                if (matrix[i][j] >= 0) {
                    sum += matrix[i][j];
                    minv = min(matrix[i][j], minv);
                } else {
                    sum += -matrix[i][j];
                    cntneg ++;
                    minv = min(-matrix[i][j], minv);
                }
            }
        }
        if (cntneg%2 == 0) {
            return sum;
        } else {
            sum -=  (long long) 2 *minv ;
        }

        return sum;
    }
};


/*
class Solution {
public:
    long long maxMatrixSum(vector<vector<int>>& matrix) {
        int r = matrix.size();
        int c = matrix[0].size();
        long long sum = 0;
        vector<int> hash;
        int cntneg = 0;
        int flag = 0;
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                if (matrix[i][j] == 0) {
                    flag = 1;
                } else if (matrix[i][j] >0) {
                    sum += matrix[i][j];
                    hash.push_back(matrix[i][j]);
                } else {
                    hash.push_back(-matrix[i][j]);
                    sum += -matrix[i][j];
                    cntneg ++;
                }
            }
        }
        if (flag || cntneg%2 == 0) {
            return sum;
        } else {
            sort(hash.begin(), hash.end());
            sum -= 2 * hash[0];
        }

        return sum;
    }
};
*/

840. 行列の魔方陣

タイトル説明:

3 x 3 の魔方陣は、1 から 9 までのさまざまな数字で満たされた 3 x 3 の行列で、各行、列、および両方の対角線の数字の合計が等しくなります。

整数の行 x 列グリッドが与えられた場合、3 × 3 の「魔方陣」部分行列はいくつありますか? (各サブマトリックスは連続しています)。

アイデア:

各行列を 3*3 行列の開始点として列挙します。

要件が満たされているかどうかの判断:

1.行と列の対角線の値が一致しているかどうか

2. 各要素が 1 ~ 9 に含まれ、1 回だけ出現するかどうか

条件が満たされた場合は 1 を返し、それ以外の場合は 0 を返します。

class Solution {
    int check(vector<vector<int>>& grid, int x, int y) {
        int hash[10];
        memset(hash, 0 ,sizeof(hash));
        int val3 = 0;
        int val4 = 0;
        int sum = grid[x][y] + grid[x][y+1] + grid[x][y+2];
        for (int i = 0; i < 3 ; ++ i) {
            int val1 = 0;
            int val2 = 0;
            for (int j = 0; j < 3; ++j) {
                if (grid[x+i][y+j] > 9 || grid[x+i][y+j] < 1 || ++hash[grid[x+i][y+j]] > 1) {
                    return 0;
                }
                val1 += grid[x+i][y+j]; //行
                val2 += grid[x+j][y+i];//列
            }
            val3 += grid[x+i][y+i]; //主对角线
            val4 += grid[x+i][y+2-i]; //副对角线
            if (sum != val1 || sum != val2 ) { //行列不相等
                return 0;
            }
        }
        if (sum != val3 || sum != val4 ) { //行列不相等
            return 0;
        }
        return 1;
    }
public:
    int numMagicSquaresInside(vector<vector<int>>& grid) {
        int ans = 0;
        int r = grid.size();
        int c = grid[0].size();
        for (int i = 0; i < r- 2; ++i) {
            for (int j = 0; j < c - 2; ++j) {
                if (check(grid, i, j)) {
                    ans ++;
                }
            }
        }
        return ans;

    }
};

おすすめ

転載: blog.csdn.net/ilovejujube/article/details/125714015