4 solutions
-
0
def real_data(N,data): matrix = [[0]*N for _ in range(N)] left, right, top, bottom = 0, N-1, 0 ,N-1 idx = 0 while left<=right and top<=bottom: for i in range(left,right+1): matrix[top][i] = data[idx] idx+=1 top+=1 for i in range(top,bottom+1): matrix[i][right] = data[idx] idx+=1 right-=1 if left<=right: for i in range(right,left-1,-1): matrix[bottom][i] = data[idx] idx+=1 bottom-=1 if top<=bottom: for i in range(bottom,top-1,-1): matrix[i][left] = data[idx] idx+=1 left+=1 return matrix def deal_data(matrix): N = len(matrix) result = [] left,right,top,bottom = 0, N-1, 0, N-1 while left<=right and top<=bottom: for i in range(top,bottom+1): result.append(matrix[i][left]) left+=1 for i in range(left,right+1): result.append(matrix[bottom][i]) bottom-=1 if top<=bottom: for i in range(bottom,top-1,-1): result.append(matrix[i][right]) right-=1 if left<=right: for i in range(right,left-1,-1): result.append(matrix[top][i]) top+=1 return result def main(): n = int(input()) data = list(map(int,input().split())) matrix = real_data(n,data) result = deal_data(matrix) print(' '.join(map(str,result))) if __name__=='__main__': main()
-
0
n = eval(input()) matrix = [[0] * n for _ in range(n)] nums = list(map(int, input().split())) if n == 1: print(nums) if n == 2: nums[1], nums[2] = nums[2], nums[1] print(nums) else: count = (n + 1) // 2 for i in range(count): for j in range(n - 2 * i): matrix[i][i + j] = nums[j] nums = nums[n - 2 * i:] for j in range(n - 2 * i - 1): matrix[i + j + 1][n - 1 - i] = nums[j] nums = nums[n - 2 * i - 1:] for j in range(n - 2 * i - 1): matrix[n - 1 - i][n - 1 - i - 1 - j] = nums[j] nums = nums[n - 2 * i - 1:] for j in range(n - 2 * i - 2): matrix[n - 1 - i - 1 - j][i] = nums[j] nums = nums[n - 2 * i - 2:] res = [] for i in range(count): for j in range(n - 2 * i): res.append(matrix[i + j][i]) for j in range(n - 2 * i - 1): res.append(matrix[n - 1 - i][i + 1 + j]) for j in range(n - 2 * i - 1): res.append(matrix[n - 1 - i - 1 - j][n - 1 - i]) for j in range(n - 2 * i - 2): res.append(matrix[i][n - 1 - i - 1 - j]) for i, num in enumerate(res): if i == len(res) - 1: print(num, end="") else: print(num, end=" ")
-
0
传统2D数组解法 可以参考一下 中等类型题
#include<bits/stdc++.h> using namespace std; vector<vector<int>> matrix; vector<int> inorder; vector<int> res; vector<vector<int>> getMatrix(vector<int>& inorder, int n) { int total = inorder.size(); vector<vector<int>> matrix = vector<vector<int>>(n, vector<int>(n , 0)); int sz = 0; int left_bound = 0, right_bound = n - 1; int up_bound = 0, lo_bound = n - 1; while(sz < total) { if (up_bound <= lo_bound) { for (int i = left_bound; i <= right_bound; i++) { matrix[up_bound][i] = inorder[sz++]; } up_bound++; } if (left_bound <= right_bound) { for (int i = up_bound; i <= lo_bound; i++) { matrix[i][right_bound] = inorder[sz++]; } right_bound--; } if (up_bound <= lo_bound) { for (int i = right_bound; i >= left_bound; i--) { matrix[lo_bound][i] = inorder[sz++]; } lo_bound--; } if (left_bound <= right_bound) { for (int i = lo_bound; i >= up_bound; i--) { matrix[i][left_bound] = inorder[sz++]; } left_bound++; } } return matrix; } vector<int> getRes(vector<vector<int>>& matrix, int n) { int left_bound = 0, right_bound = n - 1; int up_bound = 0, lo_bound = n - 1; vector<int> res; while(res.size() < n * n) { if (left_bound <= right_bound) { for (int i = up_bound; i <= lo_bound; i++) { res.push_back(matrix[i][left_bound]); } left_bound++; } if (up_bound <= lo_bound) { for (int i = left_bound; i <= right_bound; i++) { res.push_back(matrix[lo_bound][i]); } lo_bound--; } if (left_bound <= right_bound) { for (int i = lo_bound; i >= up_bound; i--) { res.push_back(matrix[i][right_bound]); } right_bound--; } if (up_bound <= lo_bound) { for (int i = right_bound; i >= left_bound; i--) { res.push_back(matrix[up_bound][i]); } up_bound++; } } return res; } int main() { int n; cin >> n; matrix = vector<vector<int>>(n, vector<int>(n, 0)); inorder = vector<int>(n * n, 0); for (int i = 0; i < n * n; i++) { cin >> inorder[i]; } matrix = getMatrix(inorder, n); res = getRes(matrix, n); for (auto i : res) { cout << i << " "; } return 0; }
-
0
原题来源
题面解释:
在本题中,我们需要处理一个 ( N \times N ) 的矩阵,每个元素为正整数,且所有正整数从 ( 1 ) 到 ( N^2 ) 恰好出现一次。给定该矩阵的顺时针遍历的结果,要求输出对应的逆时针遍历结果。输入格式为第一行包含一个整数 ( N ),表示矩阵的大小;第二行输入 ( N^2 ) 个整数,表示顺时针链表中每个元素的值。输出格式为 ( N^2 ) 个整数,表示逆时针链表的元素,以空格分隔.
模拟
对于一个大小为n的矩阵,利用一个vis数组先把周围标记墙,从(1,1)开始顺时针(右下左上(循环))模拟走,走过的位置也标记为墙体,碰到墙则进行下一个方向例如(前面一格是墙则反向顺时针旋转90度),一定能走完n*n的矩阵。还原矩阵,同理按逆时针模拟输出即可 整体时间复杂度o(n * n)
题解
在本题中,我们需要处理一个 ( N \times N ) 的矩阵,其中的每个元素都是正整数,且所有的正整数从 ( 1 ) 到 ( N^2 ) 恰好出现一次。我们首先根据给定的顺时针链表生成一个矩阵,然后输出该矩阵的逆时针遍历结果。
思路
-
初始化访问标记:首先我们定义一个
visited
数组,用来标记矩阵的访问状态。矩阵的边界视为墙体(已访问),内部位置初始为未访问。 -
顺时针填充矩阵:
- 从矩阵的左上角 (1,1) 开始,按顺时针方向(右、下、左、上)进行填充。
- 如果当前方向可以继续前进(即下一个位置未被访问),则继续向该方向前进。
- 如果碰到墙(已访问),则顺时针旋转90度,尝试下一个方向。
-
逆时针输出矩阵:
- 从填充后的矩阵的左上角开始,按逆时针方向(下、右、上、左)进行遍历输出。
- 同样地,判断下一个位置是否已访问,并适时改变方向。
-
时间复杂度:整个过程的时间复杂度为 ( O(N^2) ),因为每个位置都会被访问一次。
代码如下
cpp
#include <bits/stdc++.h> using namespace std; #define MAX_N 105 int n; // 矩阵的阶数 int seq[MAX_N * MAX_N]; // 顺时针链表中的元素值 int mat[MAX_N][MAX_N]; // 矩阵 int visited[MAX_N][MAX_N]; // 访问标记矩阵 int dxClock[4] = {0, 1, 0, -1}; // 顺时针行方向(右、下、左、上) int dyClock[4] = {1, 0, -1, 0}; // 顺时针列方向 int dxCounter[4] = {1, 0, -1, 0}; // 逆时针行方向(下、右、上、左) int dyCounter[4] = {0, 1, 0, -1}; // 逆时针列方向 // 初始化访问标记,将矩阵外边界设置为已访问 void initVisitedOuter() { for (int i = 0; i <= n + 1; i++) { for (int j = 0; j <= n + 1; j++) { visited[i][j] = 1; // 设置矩阵边界为已访问 } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { visited[i][j] = 0; // 矩阵内部未访问 } } } // 顺时针递归填充矩阵 void fillClockwise(int x, int y, int dir, int idx) { mat[x][y] = seq[idx]; // 填入顺时针链表中的值 visited[x][y] = 1; // 标记当前位置为已访问 int nx = x + dxClock[dir]; // 计算下一个位置的行坐标 int ny = y + dyClock[dir]; // 计算下一个位置的列坐标 if (visited[nx][ny] == 0) { // 如果下一个位置未访问,继续递归 fillClockwise(nx, ny, dir, idx + 1); } else { // 否则换方向 dir = (dir + 1) % 4; // 顺时针旋转方向 nx = x + dxClock[dir]; // 更新下一个位置 ny = y + dyClock[dir]; if (visited[nx][ny] == 0) { fillClockwise(nx, ny, dir, idx + 1); } } } // 逆时针读取矩阵并输出 void outputCounterClockwise(int x, int y, int dir, int idx) { if (idx != 1) cout << ' '; // 在输出前加空格,避免开头多余空格 cout << mat[x][y]; // 输出当前矩阵位置的值 visited[x][y] = 1; // 标记当前位置为已访问 int nx = x + dxCounter[dir]; // 计算下一个位置的行坐标 int ny = y + dyCounter[dir]; // 计算下一个位置的列坐标 if (visited[nx][ny] == 0) { // 如果下一个位置未访问,继续递归 outputCounterClockwise(nx, ny, dir, idx + 1); } else { // 否则换方向 dir = (dir + 1) % 4; // 逆时针旋转方向 nx = x + dxCounter[dir]; // 更新下一个位置 ny = y + dyCounter[dir]; if (visited[nx][ny] == 0) { outputCounterClockwise(nx, ny, dir, idx + 1); } } } int main() { ios::sync_with_stdio(0); // 加速输入输出 cin.tie(0); // 解除 cin 和 cout 的绑定 cin >> n; // 读取矩阵的大小 for (int i = 1; i <= n * n; i++) cin >> seq[i]; // 读取顺时针链表 initVisitedOuter(); // 初始化访问矩阵边界 fillClockwise(1, 1, 0, 1); // 从 (1, 1) 开始顺时针填充矩阵 initVisitedOuter(); // 重新初始化访问边界,用于逆时针读取 outputCounterClockwise(1, 1, 0, 1); // 从 (1, 1) 开始逆时针读取并输出 return 0; // 程序结束 }
python
import sys sys.setrecursionlimit(100005) # 增加递归深度以适应较大的矩阵 MAX_N = 105 n = 0 clockwise_values = [0] * (MAX_N * MAX_N) # 顺时针链表中的元素值 matrix = [[0] * MAX_N for _ in range(MAX_N)] # 矩阵 visited = [[0] * MAX_N for _ in range(MAX_N)] # 访问标记矩阵 dx_clock = [0, 1, 0, -1] # 顺时针方向行移动 dy_clock = [1, 0, -1, 0] # 顺时针方向列移动 dx_counter = [1, 0, -1, 0] # 逆时针方向行移动 dy_counter = [0, 1, 0, -1] # 逆时针方向列移动 # 初始化访问标记,将矩阵内部设置为未访问 def reset_inner_visited(): global visited for i in range(1, n + 1): for j in range(1, n + 1): visited[i][j] = 0 # 初始化访问标记,将矩阵外边界设置为已访问 def set_outer_boundary_visited(): global visited for i in range(n + 2): for j in range(n + 2): visited[i][j] = 1 # 顺时针递归填充矩阵 def fill_clockwise(x, y, direction, idx): matrix[x][y] = clockwise_values[idx] visited[x][y] = 1 next_x, next_y = x + dx_clock[direction], y + dy_clock[direction] if visited[next_x][next_y] == 0: fill_clockwise(next_x, next_y, direction, idx + 1) else: # 换方向 direction = (direction + 1) % 4 next_x, next_y = x + dx_clock[direction], y + dy_clock[direction] if visited[next_x][next_y] == 0: fill_clockwise(next_x, next_y, direction, idx + 1) # 逆时针读取矩阵并输出 def output_counter_clockwise(x, y, direction, idx): if idx != 1: print(' ', end='') print(matrix[x][y], end='') visited[x][y] = 1 next_x, next_y = x + dx_counter[direction], y + dy_counter[direction] if visited[next_x][next_y] == 0: output_counter_clockwise(next_x, next_y, direction, idx + 1) else: # 换方向 direction = (direction + 1) % 4 next_x, next_y = x + dx_counter[direction], y + dy_counter[direction] if visited[next_x][next_y] == 0: output_counter_clockwise(next_x, next_y, direction, idx + 1) # 主程序入口 n = int(input()) clockwise_values = [0] + list(map(int, input().split())) # 顺时针链表 set_outer_boundary_visited() # 设置矩阵外边界已访问 reset_inner_visited() # 重置内部为未访问 fill_clockwise(1, 1, 0, 1) # 顺时针填充矩阵 set_outer_boundary_visited() # 重新设置矩阵外边界 reset_inner_visited() # 重置内部为未访问 output_counter_clockwise(1, 1, 0, 1) # 逆时针输出矩阵
java
import java.util.Scanner; public class Main { static final int MAX_N = 105; static int n; // 矩阵的阶数 static int[] clockwiseValues = new int[MAX_N * MAX_N]; // 顺时针链表中的值 static int[][] matrix = new int[MAX_N][MAX_N]; // 矩阵 static int[][] visited = new int[MAX_N][MAX_N]; // 访问标记矩阵 static int[] dxClock = {0, 1, 0, -1}; // 顺时针方向行移动 static int[] dyClock = {1, 0, -1, 0}; // 顺时针方向列移动 static int[] dxCounter = {1, 0, -1, 0}; // 逆时针方向行移动 static int[] dyCounter = {0, 1, 0, -1}; // 逆时针方向列移动 // 重置矩阵的内部访问标记为未访问 static void resetInnerVisited() { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { visited[i][j] = 0; } } } // 初始化访问标记,将矩阵外边界设置为已访问 static void setOuterBoundaryVisited() { for (int i = 0; i <= n + 1; i++) { for (int j = 0; j <= n + 1; j++) { visited[i][j] = 1; } } } // 顺时针递归填充矩阵 static void fillClockwise(int x, int y, int direction, int idx) { matrix[x][y] = clockwiseValues[idx]; visited[x][y] = 1; int nextX = x + dxClock[direction]; int nextY = y + dyClock[direction]; if (visited[nextX][nextY] == 0) { fillClockwise(nextX, nextY, direction, idx + 1); } else { // 改变方向 direction = (direction + 1) % 4; nextX = x + dxClock[direction]; nextY = y + dyClock[direction]; if (visited[nextX][nextY] == 0) { fillClockwise(nextX, nextY, direction, idx + 1); } } } // 逆时针递归输出矩阵 static void outputCounterClockwise(int x, int y, int direction, int idx) { if (idx != 1) System.out.print(' '); System.out.print(matrix[x][y]); visited[x][y] = 1; int nextX = x + dxCounter[direction]; int nextY = y + dyCounter[direction]; if (visited[nextX][nextY] == 0) { outputCounterClockwise(nextX, nextY, direction, idx + 1); } else { // 改变方向 direction = (direction + 1) % 4; nextX = x + dxCounter[direction]; nextY = y + dyCounter[direction]; if (visited[nextX][nextY] == 0) { outputCounterClockwise(nextX, nextY, direction, idx + 1); } } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); for (int i = 1; i <= n * n; i++) { clockwiseValues[i] = scanner.nextInt(); } setOuterBoundaryVisited(); // 初始化矩阵外边界 resetInnerVisited(); // 重置矩阵内部未访问 fillClockwise(1, 1, 0, 1); // 顺时针填充矩阵 setOuterBoundaryVisited(); // 重新设置矩阵外边界 resetInnerVisited(); // 重置矩阵内部未访问 outputCounterClockwise(1, 1, 0, 1); // 逆时针输出矩阵 } }
-
- 1
Information
- ID
- 122
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 4
- Tags
- # Submissions
- 274
- Accepted
- 126
- Uploaded By