Codeforces Round #758 (Div.1 + Div. 2)A B
A. Find Array
题目含义:
让你构造一个长度为\(n\)的递增序列\(a\),使得\(a_{i-1}\)整除\(a_i\)
分析:
直接从\(2\)开始输出即可,因为\(2\)能被\(1\)整除,而之后的元素\(3,4,5,\cdots\)不能被较小的元素整除
int main() {
int t, n;
scanf("%d", &t);
while (t --) {
scanf("%d", &n);
for (int i = 0; i < n; i++) printf("%d ", i + 2);
printf("\n");
}
}
B. Build the Permutation
题目含义:
让你构造一个\(1\cdots n\)组成的序列,其中有个\(a\)元素满足\(p_{i-1} < p_i > p_{i+1}\),\(b\)个元素满足\(p_{i-1} > p_i < p_{i+1}\)(\(1<i<n\)),让你输出构造好的序列。
分析:
对于一个序列:
\[1,2,3,\cdots ,n-1,n
\]
如果想让该序列有一个元素,大于其两边的元素,我们可以翻转第一个元素之后的部分:\(2,\cdots ,n\),得到:
\[1,n,n-1,\cdots ,3,2
\]
类似的,如果想让该序列再有一个元素,小于其两边的元素,我们可以翻转第二个元素之后的部分,得到:
\[1,n,2,3,4,\cdots,n-1
\]
所以,如果我们想满足有\(a\)个元素大于其两边的元素,\(b\)个元素小于其两边的元素,我们需要按照上述规则操作\(a+b\)次,不过这个是对于\(a>b\)的情况而言;对于\(a\le b\),我们可以将从大到小排列,然后进行翻转。
但是多次翻转区间肯定会导致超时,所以我们可以归纳之后,用双指针的方法去模拟翻转\(a+b\)次后的结果,最终判断构造序列是否合法,输出即可。
#include <bits/stdc++.h>
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
// use these function with gun headers
#define gcd(a, b) __gcd(a, b)
#define Heap(typename) priority_queue<typename, vector<typename>, greater<typename>>
#define fputs(__str) fputs(__str, stdout)
#define _pr(__x, __y) make_pair(__x, __y)
#define _range(container) container.begin(), container.end()
#define _F(_it, _l, _r) for (int _it = (int)_l; _it <= (int)_r; _it++)
#define F_(_it, _l, _r) for (int _it = (int)_l; _it >= (int)_r; _it--)
#define umap unordered_map
#define L_B lower_bound
#define U_B upper_bound
#define LOOP int ___T; cin >> ___T; while (___T--)
// 考虑好数据范围了吗
using LL = long long;
using PII = pair<int, int>;
using VI = vector<int>;
template<class _A, class _B> LL fpow(_A A, _B B, LL mod = LONG_LONG_MAX) { LL _r = 1;
for (; B; B >>= 1, A = (A * A) % mod) if (B & 1) _r = (_r * A) % mod; return _r;};
constexpr int N = (2e5 + 114+514);
int q[N], n, a, b;
inline bool check() {
int x = 0, y = 0;
_F(i, 2, n - 1) {
if (q[i] > q[i + 1] && q[i] > q[i - 1]) x++;
if (q[i] < q[i + 1] && q[i] < q[i - 1]) y++;
if (x > a || y > b) return false;
}
return a == x && b == y;
}
int main() {
io;
LOOP {
cin >> n >> a >> b;
int l, r, cnt = a < b;
if (a >= b) {
l = 1, r = n;
_F(i, 1, a+b) {
if (i % 2) q[i] = l++;
else q[i] = r--;
cnt ++;
}
if (cnt % 2 == 0)
_F(i, a+b+1, n) q[i] = l++;
else _F(i, a+b+1, n) q[i] = r--;
}
else {
l = n, r = 1;
_F(i, 1, a+b) {
cnt ++;
if (i % 2) q[i] = l--;
else q[i] = r++;
}
if (cnt % 2 == 0)
_F(i, a+b+1, n) q[i]=r++;
else _F(i, a+b+1, n) q[i] = l--;
}
if (check())
_F(i, 1, n) cout << q[i] << ' ';
else cout << "-1"; cout << '\n';
}
return 0;
}