\(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]\)