目录
A.2022(379187662194355221)
解题思路:
经典01背包,直接套模板
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 5;
int n = 2022;
ll f[15][3000];
int main() {
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 10; j >= 1; j--) {
for (int k = i; k <= n; k++) {
f[j][k] += f[j - 1][k - i];
}
}
}
cout << f[10][n];
return 0;
}
B.钟表
解题思路:
枚举即可,再判断是否符合题目条件
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define double long double
const int N = 1e5 + 5;
int s, f, m;
bool check(double i, double j, double k) {
double j3 = 360 * k / 60;
double j2 = 360 * j / 60 + 6 * k / 60;
double j1 = 360 * i / 12 + 30 * (j * 60 + k) / 3600;
double A = fabs(j1 - j2), B = fabs(j2 - j3);
if (A > 180) A = 360 - A;
if (B > 180) B = 360 - B;
if (A == 2 * B && A != B) return 1;
else return 0;
}
int main() {
for (int i = 0; i <= 6; i++) {
for (int j = 0; j < 60; j++) {
for (int k = 0; k < 60; k++) {
if (check(i, j, k)) {
cout << i << ' ' << j << ' ' << k << endl;
}
}
}
}
return 0;
}
C.卡牌
解题思路:
二分
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;
ll n, m;
struct node {
int a, b, i;
} t[N];
bool cmp(node a, node b) {
if (a.a == b.a) return a.b < b.b;
return a.a < b.a;
}
bool cheak(int x) {
ll ans = 0;
for (int i = 1; i <= n; i++) {
if (x - t[i].a <= t[i].b) {
ans += max(0, x - t[i].a);
} else return 1;
}
if (m - ans >= 0) return 0;
return 1;
}
int find(int l, int r) {
int mid;
while (l <= r) {
mid = (l + r) >> 1;
if (cheak(mid)) r = mid - 1;
else l = mid + 1;
}
return l - 1;
}
main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) scanf("%d", &t[i].a);
for (int i = 1; i <= n; i++) scanf("%d", &t[i].b);
for (int i = 1; i <= n; i++) t[i].i = i;
sort(t + 1, t + n + 1, cmp);
int an = find(t[1].a, 900000);
if (an == 0) {
cout << t[1].a;
return 0;
}
cout << an;
return 0;
}
D.最大数字
解题思路:
使用搜索枚举所有情况
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;
string s;
int a, b;
int n[25], len;
vector<string>ans;
void dfs(int k) {
if (k > len) {
string str;
for (int i = 1; i <= len; i++) str.push_back(n[i] + '0');
ans.push_back(str);
return;
}
int x = n[k];
int y = a;
if (a >= 9 - n[k]) {
a -= 9 - n[k];
n[k] = 9;
dfs(k + 1);
n[k] = x;
a += 9 - n[k];
} else {
n[k] += a;
a = 0;
dfs(k + 1);
a = y;
n[k] = x;
}
if (b >= n[k] + 1) {
b -= n[k] + 1;
n[k] = 9;
dfs(k + 1);
n[k] = x;
b += n[k] + 1;
} else {
if (a >= 9 - n[k]) {
a -= 9 - n[k];
n[k] = 9;
dfs(k + 1);
n[k] = x;
a += 9 - n[k];
} else {
n[k] += a;
a = 0;
dfs(k + 1);
a = y;
n[k] = x;
}
}
}
int main() {
cin >> s >> a >> b;
len = s.size();
for (int i = 1; i <= len; i++) n[i] = s[i - 1] - '0';
dfs(1);
cout << *max_element(ans.begin(), ans.end());
return 0;
}
E.出差
解题思路:
图论最短路,处理一下边权,直接套模板
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e3 + 5;
#define inf 0x3f3f3f3f
int n, m;
int g[N][N];
int dis[N];
bool is[N];
int c[N];
void Dijkstra() {
for (int i = 1; i <= n; i++) dis[i] = g[1][i];
dis[1] = 0;
is[1] = 1;
for (int i = 1; i <= n; i++) {
int k = 0;
for (int j = 1; j <= n; j++) {
if (is[j] == 0 && (k == 0 || dis[j] < dis[k])) k = j;
}
is[k] = 1;
for (int j = 1; j <= n; j++) {
dis[j] = min(dis[j], dis[k] + g[k][j]);
}
}
}
int main() {
memset(g, inf, sizeof(g));
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> c[i];
int u, v, w;
for (int i = 1; i <= m; i++) {
cin >> u >> v >> w;
g[u][v] = w + c[v];
g[v][u] = w + c[u];
}
Dijkstra();
cout << dis[n] - c[n];
return 0;
}
F.费用报销
解题思路:
01背包,直接套板子
参考代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int mday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int sday[13];
int n, m, k;
struct node {
int m, d, v;
int sum;
void init() {
sum = sday[m - 1] + d;
}
} a[N];
int f[N];
int dp[N][N * 5];
bool cmp(node a, node b) {
return a.sum < b.sum;
}
int main() {
for (int i = 1; i <= 12; i++) sday[i] = sday[i - 1] + mday[i];
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) cin >> a[i].m >> a[i].d >> a[i].v, a[i].init();
sort(a + 1, a + 1 + n, cmp);
a[0].sum = -500;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
if (a[i].sum - a[j].sum >= k) f[i] = j;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = dp[i - 1][j];
if (j - a[i].v >= 0) dp[i][j] = max(dp[i][j], dp[f[i]][j - a[i].v] + a[i].v);
}
}
cout << dp[n][m];
return 0;
}
G.故障
解题思路:
参考代码:
H.机房
解题思路:
表示根节点到节点i的距离,
表示节点i的权值,那么对于两点x,y,他们的最短路时间为
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 5;
vector<int>g[N];
ll dis[N], deep[N], f[N][25], cnt[N];
int n, m;
void init(int u, int fa, ll dist) {
deep[u] = deep[fa] + 1;
f[u][0] = fa;
dis[u] = dist;
for (int i = 1; (1 << i) <= deep[u]; i++) {
f[u][i] = f[f[u][i - 1]][i - 1];
}
for (int i = 0; i < g[u].size(); i++) {
if (g[u][i] == fa) continue;
else init(g[u][i], u, dist + cnt[g[u][i]]);
}
}
int lca(int x, int y) {
if (deep[x] < deep[y]) swap(x, y);
for (int i = 20; i >= 0; i--) {
if (deep[f[x][i]] >= deep[y]) x = f[x][i];
if (x == y) return x;
}
for (int i = 20; i >= 0; i--) {
if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
}
return f[x][0];
}
inline ll get(int x, int y) {
return dis[x] + dis[y] - dis[lca(x, y)] * 2 + cnt[lca(x, y)];
}
int main() {
cin >> n >> m;
int u, v;
for (int i = 1; i < n; i++) {
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= n; i++) cnt[i] = g[i].size();
init(1, 0, cnt[1]);
for (int i = 1; i <= m; i++) {
cin >> u >> v;
cout << get(u, v) << endl;
}
return 0;
}
I. 齿轮
解题思路:
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;
int n, q, p;
int ma;
int r[N];
bool is[N];
int t[N];
void init() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j * r[i] <= ma; j++) {
if (t[j * r[i]]) is[j] = 1;
}
}
}
int main() {
cin >> n >> q;
for (int i = 1; i <= n; i++) {
scanf("%d", &r[i]);
ma = max(ma, r[i]);
t[r[i]]++;
}
init();
for (int i = 1; i <= q; i++) {
cin >> p;
if (is[p]) printf("YES\n");
else printf("NO\n");
}
return 0;
}