2023 NOI 春测 T1 ~ T3 题解
2023 NOI 春测 T1 ~ T3 题解
T1 涂色游戏
Solution
考虑
那么对于最终的格子
Code
#include<bits/stdc++.h>
using namespace std;
constexpr int _N = 1e5 + 5;
int n, m, q;
pair<int, int> L[_N], U[_N];
void Init() {
for (int i = 1; i <= n; ++i) {
L[i] = make_pair(0, 0);
}
for (int i = 1; i <= m; ++i) {
U[i] = make_pair(0, 0);
}
}
void Solve() {
cin >> n >> m >> q;
Init();
for (int i = 1, opt, x, y; i <= q; ++i) {
cin >> opt >> x >> y;
if (opt == 0) {
L[x] = make_pair(y, i);
} else {
U[x] = make_pair(y, i);
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (L[i].second > U[j].second) {
cout << L[i].first << ' ';
} else {
cout << U[j].first << ' ';
}
}
cout << '\n';
}
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T; cin >> T;
while (T--) Solve();
}
T2 幂次
Solution
我就搬个原题的题解过来吧:CF955C Sad powers
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
using i64 = long long;
i64 n, a[100005];
int k;
inline long double Qpow(int x, int y) {
long double res = 1, base = x;
for (; y; y >>= 1, base *= base) {
if (y & 1) {
res *= base;
}
}
return res;
}
inline int GetRoot(int x, int y) {
int l = 1, r = x;
while (l <= r) {
int mid = (l + r) >> 1;
if (Qpow(mid, y) > x) r = mid - 1;
else l = mid + 1;
}
return r;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> k;
i64 res = 1;
int lim = 0;
for (int i = k; ; ++i) {
int v = GetRoot(n, i);
lim = i;
if (v <= 1) break;
a[i] = v - 1;
}
for (int i = lim - 1; i >= k; --i) {
for (int j = i + i; j <= lim; j += i) {
a[i] -= a[j];
}
}
for (int i = k; i < lim; ++i) {
res += a[i];
}
cout << res << '\n';
}
T3 圣诞树
很显然的一个结论就是连接的路径一定不能相交。证明考虑相交的时候交换两个顶点的顺序一定更优。
假设已经连接的点的集合为
最终答案就是
题目要求输出方案,那么就在转移的过程中再记录一个
Code
#include<bits/stdc++.h>
using namespace std;
using Ldouble = long double;
constexpr int _N = 1e3 + 5;
int n, K;
struct Node {
Ldouble x, y;
} po[_N];
struct TriPair {
int fir, sec, thi;
TriPair() {}
TriPair(int fir, int sec, int thi) : fir(fir), sec(sec), thi(thi) {}
};
Ldouble f[_N][_N][2];
TriPair from[_N][_N][2];
inline Ldouble Sqr(Ldouble x)
{return x * x;}
inline Ldouble Dist(int i, int j)
{return sqrt(Sqr(po[i].x - po[j].x) + Sqr(po[i].y - po[j].y));}
inline int Lp(int x)
{return K - x <= 0 ? K - x + n : K - x;}
inline int Rp(int x)
{return K + x > n ? K + x - n : K + x;}
void Output(TriPair cur) {
if (cur.fir == 0 && cur.sec == 0)
return cout << K << ' ', void();
Output(from[cur.fir][cur.sec][cur.thi]);
if (cur.thi) cout << Rp(cur.sec) << ' ';
else cout << Lp(cur.fir) << ' ';
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> po[i].x >> po[i].y;
double tmpMax = -1e8;
for (int i = 1; i <= n; ++i)
if (po[i].y > tmpMax)
tmpMax = po[i].y, K = i;
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
f[i][j][0] = f[i][j][1] = 1e18;
f[0][0][0] = f[0][0][1] = 0;
Ldouble val;
for (int i = 0; i < n; ++i) {
for (int j = 0, jend = n - j; j < jend; ++j) {
if (i) {
val = f[i - 1][j][0] + Dist(Lp(i - 1), Lp(i));
if (f[i][j][0] > val)
f[i][j][0] = val, from[i][j][0] = TriPair(i - 1, j, 0);
val = f[i - 1][j][1] + Dist(Rp(j), Lp(i));
if (f[i][j][0] > val)
f[i][j][0] = val, from[i][j][0] = TriPair(i - 1, j, 1);
}
if (j) {
val = f[i][j - 1][0] + Dist(Lp(i), Rp(j));
if (f[i][j][1] > val)
f[i][j][1] = val, from[i][j][1] = TriPair(i, j - 1, 0);
val = f[i][j - 1][1] + Dist(Rp(j - 1), Rp(j));
if (f[i][j][1] > val)
f[i][j][1] = val, from[i][j][1] = TriPair(i, j - 1, 1);
}
}
}
Ldouble ans = 1e18;
TriPair pos;
for (int i = 0; i < n; ++i) {
if (ans > f[i][n - i - 1][0])
ans = f[i][n - i - 1][0], pos = TriPair(i, n - i - 1, 0);
if (ans > f[i][n - i - 1][1])
ans = f[i][n - i - 1][1], pos = TriPair(i, n - i - 1, 1);
}
Output(pos);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步