赞
踩
来自微信公众号:算法梦工厂,二维码见文末。
欢迎加入蓝桥杯备赛群:768245918,获取往届试题,测试数据,算法课程等相关资源。
#include <bits/stdc++.h> using namespace std; vector<int> Split(int x) { vector<int> ret; if (x == 0) { ret.push_back(0); return ret; } while (x > 0) { ret.push_back(x % 10); x /= 10; } return ret; } const int maxn = 2021; int rest_num[10] = {0}; bool Sub(const vector<int> &x) { for (unsigned int i = 0; i < x.size(); i++) { rest_num[x[i]]--; if (rest_num[x[i]] < 0) { return false; } } return true; } int main() { for (int i = 0; i < 10; i++) { rest_num[i] = maxn; } int ans = 1; while (1) { vector<int> need = Split(ans); bool succFlag = Sub(need); if (!succFlag) { break; } ans++; } printf("ans = %d\n", ans - 1); return 0; }
#include <bits/stdc++.h> using namespace std; struct Point { int x, y; Point() {} Point(int x, int y) { this->x = x; this->y = y; } }; struct Line { Point a, b; Line(Point a, Point b) { this->a = a; this->b = b; } }; vector<Line> lineList; double Dis(Point p0, Point p1) { return sqrt((p0.x - p1.x) * (p0.x - p1.x) + (p0.y - p1.y) * (p0.y - p1.y)); } bool CheckPointInLine(Line x, Point p) { double dis[3]; dis[0] = Dis(x.a, x.b); dis[1] = Dis(x.a, p); dis[2] = Dis(x.b, p); sort(dis, dis + 3); if (fabs(dis[0] + dis[1] - dis[2]) < 1e-5) { return true; } else { return false; } } bool CheckLineRepeat(Line cur) { for (unsigned int i = 0; i < lineList.size(); i++) { if (CheckPointInLine(lineList[i], cur.a) && CheckPointInLine(lineList[i], cur.b)) { return true; } } return false; } int main() { vector<Point> pointList; for (int i = 0; i < 20; i++) { for (int j = 0; j < 21; j++) { pointList.push_back(Point(i, j)); } } int ans = 0; for (unsigned int i = 0; i < pointList.size(); i++) { for (unsigned int j = i + 1; j < pointList.size(); j++) { Line curLine = Line(pointList[i], pointList[j]); if (!CheckLineRepeat(curLine)) { ans++; lineList.push_back(curLine); } } } printf("ans = %d\n", ans); return 0; }
#include <bits/stdc++.h> using namespace std; vector<long long int> primeNum, primeVal; void CalaPrime(long long int x) { printf("%lld = ", x); for (long long int i = 2; i * i <= x; i++) { if (x % i == 0) { int num = 0; while (x % i == 0) { x /= i; num++; } primeNum.push_back(num); primeVal.push_back(i); } } if (x > 1) { primeNum.push_back(1); primeVal.push_back(x); } for (unsigned int i = 0; i < primeNum.size(); i++) { if (i != 0) { printf(" * "); } printf("\n(%lld ^ %lld)", primeVal[i], primeNum[i]); } printf("\n"); } int main() { CalaPrime(2021041820210418); long long int ans = 0; ans = 3 * 3 * 3 * 3 * 3; ans *= 10; printf("ans = %lld\n", ans); return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 2021; vector<int> u[maxn + 52]; vector<int> v[maxn + 52]; int disDijk[maxn + 52]; int disFloyd[maxn + 52][maxn + 52]; bool vis[maxn + 52]; void InitGroup() { for (int i = 1; i <= maxn; i++) { for (int j = i + 1; j <= maxn; j++) { if (j - i <= 21) { u[i].push_back(j); v[i].push_back(i * j / __gcd(i, j)); u[j].push_back(i); v[j].push_back(i * j / __gcd(i, j)); } } } } void Floyd() { memset(disFloyd, 0x3f, sizeof(disFloyd)); for (unsigned int i = 1; i <= maxn; i++) { for (unsigned int j = 0; j < v[i].size(); j++) { disFloyd[i][u[i][j]] = v[i][j]; disFloyd[u[i][j]][i] = v[i][j]; } } for (int k = 1; k <= maxn; k++) { for (int i = 1; i <= maxn; i++) { for (int j = 1; j <= maxn; j++) { disFloyd[i][j] = disFloyd[j][i] = min(disFloyd[i][j], disFloyd[i][k] + disFloyd[k][j]); } } } printf("floyd ans = %d\n", disFloyd[1][maxn]); } void Dijkstra() { memset(disDijk, 0x3f, sizeof(disDijk)); memset(vis, 0, sizeof(vis)); disDijk[1] = 0; for (int i = 1; i <= maxn; i++) { int curMin = 0x3f3f3f3f; int curIndex = -1; for (int j = 1; j <= maxn; j++) { if (vis[j]) { continue; } if (curMin > disDijk[j] || curIndex == -1) { curMin = disDijk[j]; curIndex = j; } } vis[curIndex] = true; for (unsigned int j = 0; j < u[curIndex].size(); j++) { int t = u[curIndex][j], val = v[curIndex][j]; disDijk[t] = min(disDijk[t], disDijk[curIndex] + val); } } printf("Dijkstra ans = %d vis = %d\n", disDijk[2021], vis[2021]); } int main() { InitGroup(); Floyd(); Dijkstra(); return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 21; long long int dp[1 << maxn][maxn]; bool IsPosVis(int state, int pos) { if ((state & (1 << pos)) != 0) { return true; } else { return false; } } bool IsConnect(int x, int y) { if (x == 0 || y == 0) { return true; } if (__gcd(x + 1, y + 1) == 1) { return true; } else { return false; } } long long int f(int state, int finalPos) { if (dp[state][finalPos] != -1) { return dp[state][finalPos]; } if (!IsPosVis(state, finalPos)) { return dp[state][finalPos] = 0; } long long int ret = 0; for (int net = 0; net < maxn; net++) { if (!IsPosVis(state, net)) { continue; } if (!IsConnect(net, finalPos)) { continue; } ret += f(state - (1 << finalPos), net); } return dp[state][finalPos] = ret; } int main() { memset(dp, -1, sizeof(dp)); long long int ans = 0; int finalState = (1 << (maxn)) - 1; dp[1][0] = 1; for (int i = 0; i < maxn; i++) { long long int temp = f(finalState, i); printf("%d %d %d %lld\n", IsConnect(i, 0), finalState, i, temp); ans += temp; } printf("ans = %lld\n", ans); return 0; }
涉及知识点:动态规划,类背包问题
思路一:问题可以转化成:给定 n n n 个正整数,计算从中选出若个数字组合,每个数字可以加或者减,最终能得到多少种正整数结果。
思路二:问题还可以转化成:给定 2 ∗ n 2*n 2∗n 个正整数, a 0 , a 1 , . . . , a n , − a 0 , − a 1 , . . . , − a n a_0,a_1,...,a_n,-a_0,-a_1,...,-a_n a0,a1,...,an,−a0,−a1,...,−an ,每个数字可以选或者不选,问相加可以组合成多少种不同的正整数。这样就是一个经典的01背包问题了,只要注意一下负数问题即可。
其它技巧注意事项:
#include <bits/stdc++.h> using namespace std; const int offset = 100052; const int maxn = 100052 + offset; int n, vis[2][maxn], a[2000]; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } memset(vis, 0, sizeof(vis)); vis[0][offset] = 1; int pre = 0, cur = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < maxn; j++) { vis[cur][j] = max(vis[cur][j], vis[pre][j]); if (j - a[i] >= 0) { vis[cur][j] = max(vis[pre][j - a[i]], vis[cur][j]); } if (j + a[i] < maxn) { vis[cur][j] = max(vis[pre][j + a[i]], vis[cur][j]); } } swap(pre, cur); } int ans = 0; for (int i = offset + 1; i < maxn; i++) { if (vis[pre][i]) { ans++; } } printf("%d", ans); return 0; }
注:题目中少描述了一个信息就是, A A A 和 B B B 初始的数值都是 0 0 0 。
#include <bits/stdc++.h> using namespace std; int num[50] = {0}; void add(int x) { int cnt = 0; while (x > 0) { if (x & 1) { num[cnt]++; } cnt++; x >>= 1; } } int main() { int T, n, a, b; scanf("%d", &T); while (T--) { int xorSum = 0, temp; memset(num, 0, sizeof(num)); scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &temp); add(temp); xorSum ^= temp; } if (xorSum == 0) { printf("0\n"); continue; } int ans = 0, pos = 0; for (int i = 30; i >= 0; i--) { if (num[i] & 1) { pos = i; break; } } if (n & 1 || num[pos] == 1) { printf("1\n"); } else { printf("-1\n"); } } return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 100052; int fa[maxn], n; vector<int> u[maxn]; int dfs(int x) { int ret = 1; for (int i = 0; i < u[x].size(); i++) { int temp = 1 + dfs(u[x][i]) + u[x].size() - 1; ret = max(temp, ret); } return ret; } int main() { scanf("%d", &n); for (int i = 0; i < n - 1; i++) { scanf("%d", &fa[i]); u[fa[i]].push_back(i + 2); } printf("%d\n", dfs(1) - 1); return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 5052; const long long int MOD = 1e9 + 7; int dp[maxn][maxn]; bool vis[maxn][maxn]; char str[maxn]; int n; long long int mod(long long int x) { return x % MOD; } long long int GetAns() { memset(dp, 0, sizeof dp); memset(vis, 0, sizeof vis); dp[0][0] = 1; vis[0][0] = true; for (int i = 1; i <= n; i++) { if (str[i - 1] == '(') { for (int j = 1; j <= n; j++) { dp[i][j] = dp[i - 1][j - 1]; vis[i][j] = vis[i - 1][j - 1]; } } else { dp[i][0] = mod(dp[i - 1][0] + dp[i - 1][1]); vis[i][0] = vis[i-1][0] | vis[i-1][1]; for (int j = 1; j <= n; j++) { dp[i][j] = mod(dp[i - 1][j + 1] + dp[i][j - 1]); vis[i][j] = vis[i - 1][j + 1] | vis[i][j - 1]; } } } for (int i = 0; i <= n; i++) { if (vis[n][i] != 0) { return dp[n][i]; } } return -1; } int main() { scanf("%s", str); n = strlen(str); long long int ansL = GetAns(); reverse(str, str + n); for (int i = 0; i < n; i++) { if (str[i] == ')') { str[i] = '('; } else { str[i] = ')'; } } long long int ansR = GetAns(); printf("%lld\n", mod(ansL * ansR)); return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 152; int n, m, w[maxn], rest[maxn]; bool Check(int l, int r) { while (l <= r) { if (rest[l] == 0) { return false; } l++; } return true; } int dfs(int child, int curMax, int curMin) { if (child == m) { for (int i = 0; i < n; i++) { if (rest[i] == 2) { return 0x3f3f3f3f; } } return curMax - curMin; } int ret = 0x3f3f3f; for (int l = 0; l < n; l++) { for (int r = l; r < n; r++) { if (!Check(l, r)) { continue; } int sum = 0; for (int i = l; i <= r; i++) { sum += w[i]; rest[i]--; } int temp = dfs(child + 1, max(curMax, sum), min(curMin, sum)); for (int i = l; i <= r; i++) { rest[i]++; } ret = min(ret, temp); } } return ret; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d", &w[i]); rest[i] = 2; } int ans = dfs(0, -0x3f3f3f, 0x3f3f3f); printf("%d\n", ans); return 0; }
获取更多题解,算法讲解欢迎关注公众号:算法梦工厂
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。