每日OJ题_牛客_dd爱旋转_模拟_C++_Java
目录
牛客_dd爱旋转_模拟
题目解析
C++代码
Java代码
牛客_dd爱旋转_模拟
dd爱旋转
输入描述:
第一行一个数n(1≤n≤1000),表示矩阵大小
接下来n行,每行n个数,描述矩阵,其中数字范围为[1,2000]
一下来一行一个数q(1≤q≤100000),表示询问次数
接下来q行,每行一个数x(x=1或x=2),描述每次询问
输出描述:
n行,每行n个数,描述操作后的矩阵
题目解析
- 代数法分析:
- 对于每一种变化,我们可以用代数的方法将其表示出来
- 第一种变化:a[i][j] --> a[n - i + 1][n - j + 1]
- 第二种变化:a[i][j] --> a[n - i + 1][j]
- 最有意思的在于我们如果尝试对翻转的再翻转或者镜像的再镜像,其 i,j 的位置是会复原的(废话)
- 于是我们知道 x --> n - x + 1 这个变化是自反的(通过两次这样的变化其值又会变回 x )
- 对于每一种变化,我们可以用代数的方法将其表示出来
- 所以最后的解法:考虑使得 i,j 变成 n - x + 1 形式的操作次数,若发生偶数次则当作无事发生,否则就进行相对应的变换。
C++代码
#include <iostream>
#include <vector>
using namespace std;
int n = 0;
void func1(vector<vector<int>>& arr) // 列镜像
{
for (int j = 0; j < n / 2; ++j)
{
for (int i = 0; i < n; ++i)
{
swap(arr[i][j], arr[i][n - j - 1]);
}
}
}
void func2(vector<vector<int>>& arr) // 行镜像
{
auto tmp = arr;
int cnt = 1;
for (int i = 0; i < n / 2; ++i)
{
for (int j = 0; j < n; ++j)
{
swap(arr[i][j], arr[n - i - 1][j]);
}
}
}
int main()
{
cin >> n;
vector<vector<int>> arr(n, vector<int>(n));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cin >> arr[i][j];
}
}
int q = 0;
cin >> q;
int cnt1 = 0, cnt2 = 0;
while (q--)
{
int x = 0;
cin >> x;
if (x == 1) // 顺时针180度,列镜像?
{
++cnt1, ++cnt2;
// func1(arr);
// func2(arr);
}
else // 行镜像
{
++cnt2;
// func2(arr);
}
}
cnt1 %= 2, cnt2 %= 2;
if (cnt1)
func1(arr);
if (cnt2)
func2(arr);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
Java代码
import java.util.*;
public class Solution
{
public int LastRemaining_Solution (int n, int m)
{
int f = 0;
for(int i = 2; i <= n; i++) f = (f + m) % i;
return f;
}
}