我的第二篇,不喜勿喷
2025-08-07 17:47:24
发布于:北京
题目翻译
伊沃有一个 N×N 的表格,表格中按行主序填入了 1 到 N² 的整数。可以对表格执行以下操作:
旋转一行 —— 将一行中的所有单元格向右旋转,最后一列的数字移到第一列
旋转一列 —— 将一列中的所有单元格向下旋转,最后一行的数字移到第一行
伊沃偶尔想把数字 X 移到单元格 (R, C),操作步骤如下:
当 X 不在第 C 列时,旋转它所在的行
当 X 不在第 R 行时,旋转它所在的列
伊沃想依次移动 K 个数字。请编写程序计算每次移动所需的旋转次数。
输入格式:
第一行包含两个整数 N (2 ≤ N ≤ 10000) 和 K (1 ≤ K ≤ 1000),表示表格大小和移动次数
接下来 K 行,每行包含三个整数 X (1 ≤ X ≤ N²)、R 和 C (1 ≤ R, C ≤ N),描述一次移动。伊沃按给出的顺序执行移动
输出格式:
输出 K 行,每行对应一次移动所需的旋转次数
解题思路
核心分析
初始位置计算:
数字 X 在初始表格中的位置可以通过行主序规则计算:
行号:(X-1) // N + 1
列号:(X-1) % N + 1
旋转次数计算:
行旋转:将数字从当前列移到目标列 C 需要 (C - 当前列 + N) % N 次旋转
列旋转:将数字从当前行移到目标行 R 需要 (R - 当前行 + N) % N 次旋转
位置更新:
当旋转一行或一列时,该行 / 列中所有数字的位置都会发生变化,需要同步更新
算法步骤
读取所有移动操作,计算每个数字的初始位置
对每个移动操作:
计算行旋转次数并更新该行所有数字的位置
计算列旋转次数并更新该列所有数字的位置
输出总旋转次数(行旋转 + 列旋转)
代码实现
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, K;
cin >> N >> K;
vector<tuple<int, int, int>> moves;
unordered_map<int, pair<int, int>> pos;
// 读取所有移动并初始化位置
for (int i = 0; i < K; ++i) {
int X, R, C;
cin >> X >> R >> C;
moves.emplace_back(X, R, C);
// 计算初始位置
int r0 = (X - 1) / N + 1;
int c0 = (X - 1) % N + 1;
pos[X] = {r0, c0};
}
// 处理每个移动
for (const auto& move : moves) {
int X = get<0>(move);
int R = get<1>(move);
int C = get<2>(move);
// 获取当前位置
auto [current_r, current_c] = pos[X];
// 计算行旋转次数
int row_rotations = (C - current_c + N) % N;
// 更新当前行中所有关注数字的位置
for (auto& [Y, coordinates] : pos) {
if (coordinates.first == current_r) {
int new_c = (coordinates.second + row_rotations - 1) % N + 1;
coordinates.second = new_c;
}
}
// 计算列旋转次数
int col_rotations = (R - current_r + N) % N;
// 更新当前列中所有关注数字的位置
for (auto& [Y, coordinates] : pos) {
if (coordinates.second == C) {
int new_r = (coordinates.first + col_rotations - 1) % N + 1;
coordinates.first = new_r;
}
}
// 输出总旋转次数
cout << row_rotations + col_rotations << '\n';
}
return 0;
}
python也是有的
def main():
# 读取输入
N, K = map(int, input().split())
moves = []
for _ in range(K):
X, R, C = map(int, input().split())
moves.append((X, R, C))
# 初始化需要移动的数字的初始位置
pos = {}
for X, _, _ in moves:
# 计算初始行:(X-1) // N + 1(行主序)
r0 = (X - 1) // N + 1
# 计算初始列:(X-1) % N + 1
c0 = (X - 1) % N + 1
pos[X] = (r0, c0)
# 处理每个移动
for X, R, C in moves:
# 获取当前位置
current_r, current_c = pos[X]
# 计算需要旋转行的次数
row_rotations = (C - current_c) % N
# 更新当前行中所有我们关心的数字的位置
for Y in pos:
if pos[Y][0] == current_r:
# 向右旋转row_rotations次后的新列
new_c = (pos[Y][1] + row_rotations - 1) % N + 1
pos[Y] = (current_r, new_c)
# 计算需要旋转列的次数
col_rotations = (R - current_r) % N
# 更新当前列中所有我们关心的数字的位置
for Y in pos:
if pos[Y][1] == C:
# 向下旋转col_rotations次后的新行
new_r = (pos[Y][0] + col_rotations - 1) % N + 1
pos[Y] = (new_r, C)
# 输出总旋转次数
print(row_rotations + col_rotations)
if __name__ == "__main__":
main()
复杂度分析
时间复杂度:O (K²),其中 K 是移动次数。对于每个移动,我们最多需要更新 K 个数字的位置
空间复杂度:O (K),用于存储 K 个数字的位置信息
如果这篇题解帮你解决了问题,别忘了点个赞👍让我知道!
这里空空如也
有帮助,赞一个