#P1022. 第1题-超对称矩阵
-
1000ms
Tried: 393
Accepted: 118
Difficulty: 4
所属公司 :
阿里
时间 :2022年11月5日-淘天
第1题-超对称矩阵
题目思路
我们注意到旋转四次会对应四个格子,(除了n为奇数时中心的),然后观察可以发现 (x,y) 旋转90度后变为 (y,n−x−1)(坐标从0开始),而操作只能增加,所以把每组对应的四个格子都变成它们中的最大值即可,这种做法对于中心特殊的点也一样处理,所以不需要特判。
代码
Python代码
n = int(input())
mp = []
for i in range(n):
mp.append(list(map(int, input().split()))) #输入每个点的权值
def gt(x, y): #旋转一次
return y, n-x-1
ans = 0
for i in range(n):
for j in range(n):
mxval = mp[i][j]
for t in range(4): #旋转四次,寻找最大值
i, j = gt(i, j)
mxval = max(mxval, mp[i][j])
for t in range(4): #再旋转四次计算每个点应该操作几次
i, j = gt(i, j)
ans += mxval-mp[i][j] #更新答案
mp[i][j] = mxval #更新当前点,防止重复计算
print(ans) #输出答案
C++代码
#include <iostream>
using namespace std;
int n, m;
int mp[105][105];
void gt(int &x, int &y) {
int tmp = x;
x = y;
y = n - tmp - 1;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> mp[i][j];
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int mxval = mp[i][j];
int x=i,y=j;
for (int t = 0; t < 4; t++) { //旋转四次,寻找最大值
gt(x,y);
mxval = max(mxval, mp[x][y]);
}
for (int t = 0; t < 4; t++) {//再旋转四次计算每个点应该操作几次
gt(x,y);
ans += mxval - mp[x][y]; //更新答案
mp[x][y] = mxval; //更新当前点,防止重复计算
}
}
}
cout<<ans<<endl; //输出答案
return 0;
}
Java代码
import java.util.Scanner;
class Main {
static int n;
public static int[] gt(int a, int b) {
return new int[] { b, n - a - 1 };
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
int[][] mp = new int[105][105];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mp[i][j] = scanner.nextInt();
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int mxval = mp[i][j];
int x = i, y = j;
for (int t = 0; t < 4; t++) { // 旋转四次,寻找最大值
int[] a = gt(x, y);
x = a[0];
y = a[1];
mxval = Math.max(mxval, mp[x][y]);
}
for (int t = 0; t < 4; t++) {// 再旋转四次计算每个点应该操作几次
int[] a = gt(x, y);
x = a[0];
y = a[1];
ans += mxval - mp[x][y]; // 更新答案
mp[x][y] = mxval; // 更新当前点,防止重复计算
}
}
}
System.out.println(ans);
}
}
Js代码
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
input += data;
return;
});
process.stdin.on('end', () => {
var n;
input=input.split('\n');
n=Number(input[0][0]);
var mp=new Array(105);
for (let i=0;i<n;i++){
mp[i]=new Array(105);
for (let j=0;j<n;j++){
mp[i][j]=Number(input[i+1].split(' ')[j]);
}
}
function gt(a,b){
return [b,n-a-1];
}
var ans = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
let mxval = mp[i][j];
let x=i,y=j;
for (let t = 0; t < 4; t++) { //旋转四次,寻找最大值
let a=gt(x,y);
x=a[0],y=a[1];
mxval = Math.max(mxval, mp[x][y]);
}
for (let t = 0; t < 4; t++) {//再旋转四次计算每个点应该操作几次
let a=gt(x,y);
x=a[0],y=a[1];
ans += mxval - mp[x][y]; //更新答案
mp[x][y] = mxval; //更新当前点,防止重复计算
}
}
}
console.log(ans);
})
题目内容
小红拿到了一个 n 行 n 列的矩阵,他每次操作可以将矩阵中的某个位置+ 1 。小红想知道,自己最少操作多少次之后,可以使得矩阵变成合法矩阵?
合法矩阵的定义:当一个矩阵顺时针旋转0度、90度、180度、 270度时, 所得到的矩阵是相同的。
例如,矩阵 m 为:
3 2 1
4 5 6
7 8 9
它顺时针旋转 90 度之后就变成:
7 4 3
8 5 2
9 6 1
它顺时针旋转 180 度之后就变成:
9 8 7
6 5 4
1 2 3
输入描述
第一行输入一个正整数 n ,代表矩阵的行数和列数。
接下来的 n 行,每行输入 n 个正整数,用来表示矩阵的元素。
1≤n≤100
1≤ai,j≤109
输出描述
输出一个整数表示最少操作次数。
样例
样例一:
输入
2
1 2
2 1
输出
2
样例解释
把所有的数都变成 2 ,需要 2 次操作。
样例二:
输入
5
1 5 3 2 4
3 1 4 2 3
4 5 1 5 3
2 4 5 1 3
4 5 2 1 3
输出
33