I was lucky enough to save 1 this time, so I specially reviewed the problem solutions, hahaha...
1. Hexadecimal conversion (5 points):
Problem Description:
Calculate directly 2 + 2 * 9 + 2 * 9 * 9 * 9
Answer: 1478
2. Shun Zi date (5 points)
This question is controversial: the main reason is that 0 and so on cannot start: such as 20220121
I don't think 0 can be used as the beginning (because the sequence shown in 20220123 in the example is 123 and not 012):
So the Shunzi dates have: 20220123 20221123 20221230 20221231
Answer: 4
3. Question statistics (10 points)
Problem-solving ideas:
- Consider the case of a=1, b=1, n=1e18, it cannot be calculated day by day, and it will time out
- 5 * a+2 * b is the amount of questions for a week, first calculate how many weeks by division,
- The number of remaining days keeps decreasing.
- if (n <= 0)break; should be placed first
Reference Code:
#include<iostream>
using namespace std;
int main()
{
long long a, b, n;
cin >> a >> b >> n;
long long day = 0;
long long t = n / (5 * a + 2 * b);
day += t * 7; //先算多少周
n = n % (5 * a + 2 * b);
for (int i = 1; i <= 7; i++) {
//再算天数
if (n <= 0)break;
if (i > 5)n -= b;
else n -= a;
day++;
}
cout << day;
return 0;
}
4. Pruning shrubs (10 points)
Ideas:
- For each point, the distance from the 1 endpoint and the distance from the n endpoint need to be considered
- Because of cutting back and forth, you need to divide the distance * 2
- Then take the larger value of the two
- The case of final judgment 1
Reference Code:
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if (n == 1) {
cout << 1 << endl;
return 0;
}
for (int i = 1; i <= n; i++) {
cout << max(2 * (i - 1), 2 * (n - i))<< endl;
}
}
5. X base subtraction (15 points)
Algorithm: simple greedy
Let’s first analyze how the 65 of the question came out:
- Every number represented by the first digit must be 1
- The second digit comes from the binary of the first digit, so each number of the second digit represents 2
- The third digit is derived from the second digit in decimal, so each number of the third digit represents 2 * 10 = 20
So: X(321) = 3 * 20 + 2 * 2 + 1 * 1 = 65;
Reference Code:
#include<iostream>
using namespace std;
const int N = 1e5 + 10,MOD=1e9+7;
int a[N], b[N];
int n, ma, mb;
int main()
{
cin >> n;
cin >> ma;
for (int i = ma - 1; i >= 0; i--)cin >> a[i];
cin >> mb;
for (int i = mb - 1; i >= 0; i--)cin >> b[i];
long long t = 1; //到每一个的底数
long long ans=0;
for (int i = 0; i < ma; i++) {
int c = max(a[i], b[i]) + 1; //贪心取得最小的进制
if (c < 2)c = 2; //最小为2进制
ans = (ans+(a[i] - b[i]) * t)%MOD;
t = (t * c) % MOD;
}
cout<<ans;
}
6. Statistics sub-matrix (15 points)
Algorithm: Two-dimensional prefix sum
Note: In theory, the simple prefix sum will time out on 100% of the data and needs to be optimized , as long as the sub-matrix is not repeatedly calculated.
#include<iostream>
using namespace std;
const int N = 510;
int g[N][N];
int n, m, k;
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> g[i][j];
g[i][j] += g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1];
}
}
/*
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << g[i][j] << " ";
}
cout << endl;
}*/
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int x = i; x <= n; x++) {
for (int y = j; y <= m; y++) {
if (g[x][y] - g[x][j - 1] - g[i - 1][y] + g[i - 1][y - 1] <= k)ans++;
}
}
}
}
cout << ans;
}
7. Block painting (20 points)
Algorithms: Dynamic Programming
Ideas:
Conversion equation : dp[i] is converted from dp[i-1] , dp[i-2], dp[i-3] states
- There is only one possibility to go from dp[i-1] to dp[i]
So dp[i] = dp[i-1] * 1
- There is only one possibility from dp[i-2] to dp[i] (the situation in 1 needs to be excluded)
So dp[i] = dp[i-2] * 1
- From dp[i-3] to dp[i], there are two possibilities (need to exclude 1, 2 cases)
So dp[i] = dp[i-3] * 2
综上 : dp[i] = dp[i-1] + dp[i-2] +dp[i-3] * 2
Initial state : dp[0] = 1 , dp[1] = 1 , dp[2] = 2
Final state transition equation : dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3] * 2)%MOD;
Reference Code:
#include <iostream>
using namespace std;
const int N = 1e7 + 4, MOD = 1000000007;
int dp[N]; //dp[i]表示长度为i有dp[i]个拼法
int n;
int main() {
cin >> n;
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3] * 2)%MOD;
}
cout << dp[n] ;
return 0;
}
8. Minesweeper (20 points)
Algorithm: DFS
Ideas:
- The detonated mine can be considered a demining rocket
- Every mine-clearing rocket is detonated, and all mines are traversed, if it is within the range, the mine is detonated
- The detonated mine needs to be marked to prevent repeated detonation
Reference Code:
#include <iostream>
using namespace std;
const int N = 50010;
struct Node {
int x, y, r;
};
int n, m,ans=0;
Node mine[N];
bool visited[N];
Node rocket[N];
bool compare(Node a, Node b) {
long xx = (a.x-b.x) * (a.x - b.x);
long yy = (a.y-b.y) * (a.y - b.y);
return sqrt(xx+yy) <= a.r;
}
void boom(Node node) {
for (int i = 0; i < n; i++) {
if (visited[i])continue;
if (compare(node, mine[i])) {
visited[i] = true;
ans++;
boom(mine[i]);
}
}
}
int main() {
cin >> n >> m;
int x, y, r;
for (int i = 0; i < n; i++) {
cin >> x >> y >> r;
mine[i] = {
x,y,r };
}
for (int i = 0; i < m; i++) {
cin >> x >> y >> r;
rocket[i] = {
x,y,r };
}
for (int i = 0; i < m; i++) {
boom(rocket[i]);
}
cout << ans;
return 0;
}
9. Li Bai Dajiu Enhanced Version
Algorithms: Dynamic Programming
State representation : f[i][j][k] indicates the number of plans when visiting the first i locations, visiting exactly j stores and drinking exactly k;
State transition :
- Looking at flowers: f[i][j][k] = f[i-1][j-1][k+1]
- 遇店 :f[i][j][k] = f[i-1][j][k/2];
Initial state : f[0][0][2] just started 2 buckets of wine
Notice:
- When looking at flowers , you need to ensure that j>1 (it is impossible to look at flowers before the last time, but this time you will still look at flowers)
- When looking at the store, you need to ensure that the number of wine is even, because doubling is always an even number
Reference Code:
#include <iostream>
using namespace std;
const int N = 110,MOD = 1e9+7;
int n, m;
int f[2*N][N][N]; //f[i][j][k] 表示在第i个位置(共有 n+m个位置),遇到j个花,目前还剩 k斗酒
int main() {
cin >> n >> m;
f[0][0][2] = 1;
for (int i = 1; i <= n + m; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= m; k++) {
//酒的最大数量为m,如果大于m,就算后面的全是花也喝不完酒
//遇到花
if(j>=1) f[i][j][k] =f[i - 1][j - 1][k + 1];
//遇到酒
if (k % 2 == 0) {
//
f[i][j][k] = (f[i][j][k]+f[i - 1][j][k / 2])%MOD;
}
}
}
}
cout << f[n + m - 1][m - 1][1];
return 0;
}
10. Cut bamboo
Do the previous ones first, but don’t make them! ! ! !
Final summary:
The Blue Bridge Cup has changed. It is no longer the previous violent cup. It is a test of thinking. DFS and dynamic programming will become frequent visitors. In the future, friends should do more questions, do more questions, do more questions! ! !