A.Filling Diamonds
题意:
给定个菱形,要将它们组成一个钻石,问所有的摆放方案
题解:
其实可以发现每个钻石只有一个菱形是立着的,所以方案数就是一个钻石内能立着的位置数,可以发现刚好是
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 3e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 998244353; void solve() { int n; scanf("%d", &n); printf("%d\n", n); } int main() { int t; for (scanf("%d", &t); t >= 1; t--) solve(); }
B.Sorted Adjacent Differences
题意:
给定一个数组,要求重新排列,使得相邻两个元素的差值单调不降。
题解:
先将升序排序,然后从中间开始分别从两边取一个数
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 998244353; int a[maxn]; void solve() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); sort(a + 1, a + n + 1); int mid = n / 2 + 1; int l = mid - 1, r = mid + 1; printf("%d ", a[mid]); while (l >= 1 || r <= n) { if (l >= 1) printf("%d ", a[l--]); if (r <= n) printf("%d ", a[r++]); } puts(""); } int main() { int t; for (scanf("%d", &t); t >= 1; t--) solve(); }
C.Powered Addition
题意:
给你一个数组,你可以在第秒选一些元素让它们加,询问最短的时间使得数组变成单调不降
题解:
考虑到二进制的性质,那么这道题实际就是找,因此只需要
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 998244353; int a[maxn]; void solve() { int n, x, y, mx = 0; scanf("%d", &n); scanf("%d", &x); for (int i = 1; i < n; i++) { scanf("%d", &y); if (x > y) mx = max(mx, x - y); x = max(x, y); } printf("%d\n", (int)ceil(log2(mx + 1))); } int main() { int t; for (scanf("%d", &t); t >= 1; t--) solve(); }
D.Edge Weight Assignment
题意:
给你一棵个节点的树,要求给每一条边一个权值,要满足任意两个叶节点的路径上的边的权值异或和为。询问最少和最多的种类
题解:
先考虑最少的情况,各个叶子节点到根的距离的奇偶性如果一样,那么所有边权都可以相等,只需要一种,否则的话只需要用三个数即可,如样例2
再考虑最多的情况,理想条件肯定是每一条边都填上不同的数字,那么最大值为,但是当个叶子节点连接同一个节点时,很明显这个叶子节点的邻边边必须填相同的数,我们在的基础上减即可
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 2e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 998244353; vector<int> G[maxn]; int ans; int c[3], dep[maxn]; void dfs(int u, int fa) { int cnt = 0; for (int v : G[u]) { if (v == fa) continue; dep[v] = dep[u] + 1; if (G[v].size() == 1) { c[dep[v] & 1]++; cnt++; } else dfs(v, u); } if (cnt >= 2) ans -= cnt - 1; } int main() { int n; scanf("%d", &n); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } int rt; for (int i = 1; i <= n; i++) if (G[i].size() > 1) { rt = i; break; } ans = n - 1; dfs(rt, 0); printf("%d %d\n", c[0] && c[1] ? 3 : 1, ans); return 0; }
E.Perfect Triples
题意:
给定一个无限长的序列,每次将一个三元组加入,要求三元组满足:
- 均不在中
- 三元组是所有满足条件中字典序最小的
给定组询问,每次询问给定一个要求给出中的第的数,
题解:
显然是个结论题,打表找找规律
贴一下一位博主这题的打表结论,原博客戳我~
四进制下
001 002 003
//1行
010 020 030
011 022 033
012 023 031
013 021 032
//1<<2行
100 200 300
101 202 303
102 203 301
103 201 302
110 220 330
111 222 333
112 223 331
113 221 332
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 998244353; ll f[4] = {0, 2, 3, 1}; ll B(ll a) { return (a == 1) ? 2 : f[a & 3] | B(a >> 2) << 2; } int main() { int t; scanf("%d", &t); while (t--) { ll n, A[3]; scanf("%lld", &n); ll d = 1; for (; n >= d; d <<= 2); d >>= 2; A[0] = d | ((n - d) / 3); A[1] = B(A[0]); A[2] = A[0] ^ A[1]; printf("%lld\n", A[(n - d) % 3]); } }