2022 Blue Bridge Cup C++ Group B problem solution - very detailed

I was lucky enough to save 1 this time, so I specially reviewed the problem solutions, hahaha...

insert image description here

1. Hexadecimal conversion (5 points):

Problem Description:

insert image description here

Calculate directly 2 + 2 * 9 + 2 * 9 * 9 * 9

Answer: 1478

2. Shun Zi date (5 points)

insert image description here

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)

insert image description here

Problem-solving ideas:

  1. Consider the case of a=1, b=1, n=1e18, it cannot be calculated day by day, and it will time out
  2. 5 * a+2 * b is the amount of questions for a week, first calculate how many weeks by division,
  3. The number of remaining days keeps decreasing.
  4. 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)

insert image description here

Ideas:

  1. For each point, the distance from the 1 endpoint and the distance from the n endpoint need to be considered
  2. Because of cutting back and forth, you need to divide the distance * 2
  3. Then take the larger value of the two
  4. 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)

insert image description here
insert image description here

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)

insert image description here

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)

insert image description here

insert image description here

Algorithms: Dynamic Programming

Ideas:

Conversion equation : dp[i] is converted from dp[i-1] , dp[i-2], dp[i-3] states

  1. There is only one possibility to go from dp[i-1] to dp[i]

insert image description here

So dp[i] = dp[i-1] * 1

  1. There is only one possibility from dp[i-2] to dp[i] (the situation in 1 needs to be excluded)

insert image description here

So dp[i] = dp[i-2] * 1

  1. From dp[i-3] to dp[i], there are two possibilities (need to exclude 1, 2 cases)

insert image description here

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)

insert image description here
insert image description here

Algorithm: DFS

Ideas:

  1. The detonated mine can be considered a demining rocket
  2. Every mine-clearing rocket is detonated, and all mines are traversed, if it is within the range, the mine is detonated
  3. 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

insert image description here

insert image description here

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 :

  1. Looking at flowers: f[i][j][k] = f[i-1][j-1][k+1]
  2. 遇店 :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

insert image description here

insert image description here

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! ! !

It's not easy to create, I hope you guys will come in three consecutive waves! ! ! ! I wish you all the best next time! ! !

Guess you like

Origin blog.csdn.net/The_xiaoke/article/details/124518533