$CF\ 633\ (Div2)$

\(CF\ 633\ (Div2)\)

\(A.\)

水题

竖着的菱形决定了横着的菱形,所以答案即为竖着的菱形个数,即 \(n\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 1e6 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
 
 
inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}
 
int main()
{
    int t;
    scanf("%d", &t);
    while(t--) {
        int n; scanf("%d", &n);
        printf("%d\n", n);
    }
    return 0;
}

\(B.\)

先排序,然后首尾取,即可构造答案,最后倒序输出即可

正确性证明:

设头为 \(i\),尾为 \(j\),倒数第二个为 \(k\)

满足 \(i\leq k\leq j\)

所以 \(j - i\geq k - i\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 1e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int t, n, cnt, a[N], ans[N];
int main()
{
    scanf("%d", &t);
    while(t--) {
        memset(ans, 0, sizeof(ans));
        cnt = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) a[i] = read();
        sort(a + 1, a + 1 + n);
        int x = n, y = 1;
        while(cnt < n)
            ans[++cnt] = a[x--], ans[++cnt] = a[y++];
        for(int i = n; i >= 1; --i)
            printf("%d%c", ans[i], " \n"[i == 1]);
    }
    return 0;
}

\(C.\)

对于每对 \(i,\ j,\ i < j\), 若 \(a[i] > a[j]\),那么 \(a[j]\) 必须通过增值来越过 \(a[i]\)

设时间为 \(t\),则增长的最大值为 \(2^{t} - 1\)

那么 \(t = \left\lceil log2(a[i] - a[j] + 1)\right\rceil\)

若存在 \(k\) 介于 \(i,\ j\) 之间

  • \(a[k]\leq a[j]\),那么 \(a[k],\ a[j]\) 一同增值越过 \(a[i]\),仍然保证了 \(a[k],\ a[j]\) 的相对大小
  • \(a[k] > a[j]\),那么让 \(a[k]\) 某些时刻不增值,\(a[j]\) 增值即可

遍历答案,找到最大的 \(a[i] - a[j],\ i < j\),算出对应的 \(t\) 即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 1e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;


inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int t, n;
int main()
{
    t = read();
    while(t--) {
        n = read();
        int x = -inf, ans = 0;
        for(int i = 1; i <= n; ++i) {
            x = max(x, a[i]);
            ans = max(ans, x - a[i]);
        }
        ans = ceil(log2(ans + 1));
        printf("%d\n", ans);
    }
    return 0;
}

比赛时纠结的一个点是

\(a[k] > a[j]\),是否能保证增值后满足 \(a[k]\leq a[j]\)

事实上这是可以保证的,因为 \(a[j]\) 为了越过 \(a[i]\),最大增值可以是 \(2^{t} - 1\)

不管 \(a[k]\)\(a[j]\) 大多少,都可以先让 \(a[j]\) 追上 \(a[k]\),然后一起增值超过 \(a[i]\)

猜你喜欢

转载自www.cnblogs.com/ChenyangXu/p/12693013.html