(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], "
"[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);
}
return 0;
}
(B.)
先排序,然后首尾取,即可构造答案,最后倒序输出即可
正确性证明:
设头为 (i),尾为 (j),倒数第二个为 (k)
满足 (ileq kleq j)
所以 (j - igeq 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], "
"[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], "
"[i == 1]);
}
return 0;
}
(C.)
对于每对 (i, j, i < j), 若 (a[i] > a[j]),那么 (a[j]) 必须通过增值来越过 (a[i])
设时间为 (t),则增长的最大值为 (2^{t} - 1)
那么 (t = leftlceil log2(a[i] - a[j] + 1) ight ceil)
若存在 (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], "
"[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
", 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])