Blue Bridge Cup Training 1: Search for real questions (the diameter of a tree is more interesting)

Question 1: Mixed number

Training Problem 1: Mixed Score

My AC code:

#include <iostream>
#include <algorithm>
using namespace std;

int GetNum(int a[], int begin, int end) {
    
    
	int num = 0;
	for (int i = begin; i < end; ++i)
		num = num * 10 + a[i];
	return num;
}

int main() {
    
    
	int n, len = 0, a[9] = {
    
     1, 2, 3, 4, 5, 6, 7, 8, 9 };
	cin >> n;
	int Temp = n, ans = 0;
	while (Temp) {
    
    
		Temp /= 10;
		len++;
	}
	do {
    
    
		int num = 0;
		for (int i = 0; i < len; ++i) {
    
    
			num = num * 10 + a[i];
			if(num >= n)
				break;
			int k = n, j = 9 - (i + 1);
			k -= num;
			int mid = (j >> 1) + 1;
			while (mid < 9) {
    
    
				int num1 = GetNum(a, i + 1, mid);
				int num2 = GetNum(a, mid, 9);
				if (0 == num1 % num2 && k == num1 / num2)
					ans++;
				mid++;
			}
		}
	} while (next_permutation(a, a + 9));
	cout << ans;
	return 0;
}

Question 2: Cut the grid

Training Problem 2: Cut the grid

My AC code:

#include <iostream>
using namespace std;

const int maxn = 12;
int n, m, a[maxn][maxn], vis[maxn][maxn], sum, ans;
int dir[4][2] = {
    
     {
    
    0, 1},{
    
    0,-1},{
    
    1,0},{
    
    -1,0} };
void dfs(int x, int y, int cnt, int blank) {
    
    
	if (cnt * 2 >= sum) {
    
    
		if (blank > ans && cnt * 2 == sum)
			ans = blank;
		return;
	}
	for (int i = 0; i < 4; ++i) {
    
    
		int dx = x + dir[i][0], dy = y + dir[i][1];
		if (dx >= 0 && dx < n && dy >= 0 && dy < m) {
    
    
			if (!vis[dx][dy]) {
    
    
				vis[dx][dy] = 1;
				dfs(dx, dy, cnt + a[dx][dy], blank + 1);
				vis[dx][dy] = 0;
			}
		}
	}
}
int main() {
    
    
	cin >> m >> n;
	for(int i = 0;i < n;++i)
		for (int j = 0; j < m; ++j)
		{
    
    
			cin >> a[i][j];
			sum += a[i][j];
		}
	if (sum & 1)
		cout << 0;
	else {
    
    
		dfs(0, 0, a[0][0], 1);
		cout << ans;
	}
	return 0;
}

Third question: Minister’s travel expenses

Minister's travel expenses

My 75 points of pure violence (timeout):

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int maxn = 10005;
struct Edge {
    
    
	int dest, cost;
	Edge(int d, int c) :dest(d), cost(c) {
    
      }
};
vector<Edge> G[maxn];
int n, ans, cnt, vis[maxn];
int dfs(int p, int Len) {
    
    
	if (vis[p]) 
		return cnt;
	if (cnt < Len)
		cnt = Len;
	vis[p] = 1;
	for (int i = 0; i < (int)G[p].size(); ++i) 
		if (!vis[G[p][i].dest])
			dfs(G[p][i].dest, Len + G[p][i].cost);
	return cnt;
}
int main() {
    
    
	scanf("%d", &n);
	for (int i = 1; i < n; ++i) {
    
    
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		G[a].push_back(Edge(b, c));
		G[b].push_back(Edge(a, c));
	}
	for (int i = 1; i <= n; ++i) {
    
    
		int Temp = dfs(i, 0);
		if (ans < Temp)
			ans = Temp;
		cnt = 0;
		memset(vis, 0, sizeof(vis));
	}
	printf("%d", ans * 10 + (ans + 1) * ans / 2);
	return 0;
}

Analysis of Algorithms:

This question is to find the diameter of the tree, so let’s just talk about this algorithm: the diameter of the tree

First explain the noun: the diameter of the tree

Because the tree is a special data structure, any two points on the tree can be interconnected, and there is only one way to connect! Because the tree is the largest acyclic graph, the smallest connected graph! Then since any two points can be interconnected, the distance between two points must be the largest among all the point pairs composed of two points! To find the maximum value is to find the diameter of the tree!
how? Does the diameter of the tree fit the characteristics of the subject?

Then explain the algorithm: the diameter of the dfs solution tree

First explain a truth:

The furthest point that can be reached from any point must be an end point of the diameter of the tree!
why? This can be disproved: Suppose that any point p is selected
because there is a path from the end of the tree diameter to point p. Assume that the end points are A and B. If the farthest point that can be reached from p is not A or B, but C , Then starting from A (or B), the farthest point that can be reached is not B (or A)! You can draw this on paper and you will find it!

Talk about the algorithm steps in detail:

The first dfs: Find the point A farthest from the starting point p, which is an end of the diameter. The
second dfs: Starting from the end of the diameter, find the farthest point. This distance is the diameter!

In this way, from the first n dfs to 2 dfs, you can pass!

My AC code:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int maxn = 10005;
struct Edge {
    
    
	int dest, cost;
	Edge(int d, int c) :dest(d), cost(c) {
    
      }
};
vector<Edge> G[maxn];
int n, ans = -1, MaxPoint = -1, vis[maxn];
void dfs(int p, int Len) {
    
    
	if (vis[p]) 
		return ;
	if (ans < Len) {
    
    
		ans = Len;
		MaxPoint = p;
	}
	vis[p] = 1;
	for (int i = 0; i < (int)G[p].size(); ++i) 
		if (!vis[G[p][i].dest])
			dfs(G[p][i].dest, Len + G[p][i].cost);
	return ;
}
int main() {
    
    
	scanf("%d", &n);
	for (int i = 1; i < n; ++i) {
    
    
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		G[a].push_back(Edge(b, c));
		G[b].push_back(Edge(a, c));
	}
	dfs(1, 0);
	ans = -1;
	memset(vis, 0, sizeof(vis));
	dfs(MaxPoint, 0);
	printf("%d", ans * 10 + (ans + 1) * ans / 2);
	return 0;
}

Exercise summary:

To be honest, most of the front-end time has been devoted to the research and coding of cryptography, followed by the practice of object-oriented programming. I have not done algorithm training for a while (ashamed!) The arrival of the Blue Bridge Cup, as well as csp, ladder competition, Xi'an Invitational and so on, these will be held after the epidemic is over, we still have to step up training! These questions are not difficult search training questions. The diameter of the tree is more interesting and worthy of attention!

Guess you like

Origin blog.csdn.net/qq_44274276/article/details/104844474