题目大意 $b_i$ 为 $a$ 中前 $i$ 个数的最大值。定义操作:把排列 $a$ 向后移动一位(即原本最后一个数成为第一个数,其它数依次后移)。$c_i$ 为 $a$ 移动 $i-1$ 位后,每次生成的 $b_i$ 数组中不同的数的个数。
现在给定 $c$ 数组,判断是否存在对应的排列 $a$。
原题链接
思路 假设已经移动了 $k$ 次,每次移动后,最后一个数会到第一个,其它数的顺序不变。也就是说:
如果 $a_n < a_1$:新的第一个数不超过当前最大值,$c[k+1] = c[k] + 1$。
如果 $a_n > a_i$:当前最大值可能失效,$c[k+1] < c[k]$。
也就是说,我们只需要判断 $c$ 数组中是否存在 $c[k] > c[k-1] + 1$ 即可。
但是需要注意的是,我们任意向右移动 $c$ 数组,也应该存在相应的 $a$ 数组,即 $c[1] - c[n] \le 1$,我们需要特判一下这个条件。
一种直接做法是,我们不妨直接通过向右移动,把 $1$ 转到第一位,这样显然满足 $c[1] - c[n] < 1$。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <bits/stdc++.h> using namespace std; void solve () { int n; cin >> n; vector<int > a (n) ; for (int &v: a) cin >> v; if (count (a.begin (), a.end (), 1 ) != 1 ) { cout << "NO\n" ; return ; } int p = find (a.begin (), a.end (), 1 ) - a.begin (); rotate (a.begin (), a.begin () + p, a.end ()); for (int i = 1 ; i < n; ++i) { if (a[i] - a[i - 1 ] > 1 ) { cout << "NO\n" ; return ; } } cout << "YES\n" ; } int main () { ios_base::sync_with_stdio (false ); cin.tie (NULL ); int t; cin >> t; while (t--) solve (); return 0 ; }