原题
题目大意
有一个长度为n,数组元素为1~你懂的数组数组。第 i 次操作可以将前 i 个元素循环右移任意个位置,求每次操作移动几个位置可以得到所给数组
思路
- 第i次操作只对前i个元素进行循环右移,可发现与
i+1
及其之后的元素无关 - 我们可以发反过来想,确定第i个元素移动几次之后求第
i-1
个元素的移动位置时就可以不用管了 - 所以从最后一个位置开始枚举
- 确定第i个元素的移动次数后,要将前期前面的数字恢复到i移动之前的状态,可以理解为向左移对应的位置
code
#include<bits/stdc++.h>
using namespace std;
int n , m, k, t;
void solve()
{
cin >> n;
vector<int>a(n + 1), b(n +1);
for(int i = 1; i <= n; i ++)
{
int u;
cin >> u;
a[u] = i;
}
for(int i = n; i >= 1;i --)
{
int v = a[i];
b[i] = v % i;
//现有位置对按顺序应该在的位置取余即可得到移动了几个位置
for(int j = 1; j <= i;j ++)
a[j] = (a[j] + i - v) % i;
}
for(int i = 1; i <= n; i ++) cout << b[i] << " ";
puts("");
}
int main()
{
cin >> t;
while(t --)
{
solve();
}
return 0;
}