Loading

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;
}
posted @ 2021-12-11 23:42  Frank_Ou  阅读(87)  评论(0编辑  收藏  举报