2020 Blue Bridge Cup first round of provincial group B questions solutions (with questions)

Preface

No. 4 provincial competition, there is still no solution to this day. Simply write one by yourself. Of course it is not a standard answer. It is purely a personal understanding. There may be errors. Please correct me. I personally think that the quality of the questions in this provincial competition is good, they are all writeable questions, and the difficulty gradient is also good. The last question may be simple.
The answer to fill in the blank is not saved, so just write the idea solution.
The programming questions will be filled with code later.

A Running training

There are many similar problems, such as snail climbing trees, climbing wells and so on. It can be calculated directly or programmed to simulate. It should be noted that the remaining physical strength in the last minute of running is 400 instead of 100.

B anniversary

There is nothing to say, just do the calculations. I heard that there is a function in excel to get the number of days directly.

C merge detection

Assuming that the total is 1, the combined test needs to consume 1/K kits of reagents. Among them, 0.01 infected persons need to spend an additional 0.01*K kits of reagents, that is, a total of 1/K+K/100 kits of reagents are required. K is obtained according to the basic inequality Take 10.

D REPEAT program

You can write a translation program, or you can use tricks to change the replacement text into code, and then run it directly.
If you write a translation program, you can write a dfs. Every time you find a repeat, a new call is made. I use the indentation for the passed parameters to get the priority. The longer indentation needs to be calculated first to get the result. You can return to the upper level when the indentation of this line is less than the parameter.
Give a translation program I wrote, based on dfs processing nested REPEAT

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

const int maxn = 1000010;
string s[1005];
int i = 0;
int getp(string s)
{
    
    
	int p = 0;
	while(s[p] == ' ')p++;
	return p;
}
int x = 0;
int dfs(int y)
{
    
    
	int p = 0,v = 0;
	while(x<i){
    
    
		x++;
		cout << s[x] << endl << x << ' ' << y << ' ' << v << endl;
		p = getp(s[x]);
		if(p<y){
    
    
			x--;
			return v;
		}
		if(s[x][p] == 'R')
		{
    
    
			v+=(s[x][p+7]-'0')*dfs(p+4);
		}
		else if(s[x][p] == 'A'){
    
    
			v+=s[x][p+8]-'0';
		}

	}
	return v;
}
int main()
{
    
    
    freopen("prog.txt","r",stdin);

    long long ans = 0;
    //getline(cin,s[0]);
    while(!cin.eof()){
    
    
    	getline(cin,s[i]);
    	i++;
    }
    ans = dfs(0);
    cout << ans;
	return 0;
}

E matrix

After observation, it can be found that the upper left and lower right can only take 1, 2020; and the two grids adjacent to 1, that is, one row, two columns and two rows and one column, can only take 2, 3; move one column back, that is, one row, three columns and Two rows and two columns, only 4 and 5 can be taken; inferring that there are a total of 1009 groups, then the answer is 2^1009mod2020.

F divisible sequence

As the title suggests, just execute the loop division by 2 directly on the input.

G decoding

It can be output in pre-reading mode, that is, read two characters at a time and see if the second digit is a number. If it is not, output the current character, if it is, output the current character of the specified number and position +1; it can also be directly sequenced Output, compensate the previous digit every time a number is read.

H go square

Simple dp is enough, dp[i][j]=dp[i-1][j]+dp[i][j-1].
It can also be solved by dfs, but it may time out when the value is close to 30. I made a chart.

I integer splicing

The splicing number can be regarded as composed of two parts, the first part is a*10^b, the second part is c, so we can preprocess the first part, and then query how many numbers like the first part are for each c To satisfy the sum of the two parts modK=0, just add ans.

The specific method is to create a two-dimensional array mod, one-dimensional represents the power of 10, and two-dimensional represents the remainder of modK. Calculate the remainder of the product modK of each number and 10, 100, 1000...10^9, and then +1 the unit of the corresponding two-dimensional array. After processing, mod[a][b] means that a number is followed by a 0, and the remainder of modK is b, which is the number of such numbers (the first part mentioned above). Then process each number. Assuming that this number is the second part of the splicing number mentioned above, then the first part that meets the conditions modK is added to this number modK, and the result of modulo K should be 0.

To facilitate processing, I wrote two functions, one getl, which returns the number of digits of the passed in value; one getll, which returns the power of 10. In this way, when processing each number a, we can directly access the mod array obtained by preprocessing. One dimension is getl(a), which means how many 0s must be followed in the first part, and the second part is (Ka modK) modK, which means that the sum of the two parts modK is 0. The result obtained is the number of a*10^b that meets the condition.

What you need to pay attention to is the match between yourself and yourself, that is, the a in the first part and the c in the second part are the same number. We can check whether the current number a is multiplied by getll(a) to modulo K during processing, and whether it is the same as the remainder (Ka modK) modK we need. If it is the same, it means that the number of the remainder includes the number currently being processed, and ans should be -1.

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 100010;
int mod[10][maxn];
long long a[maxn];
int getl(long long a)
{
    
    
	int r = 0;
	while(a>0)
	{
    
    
		r++;
		a/=10;
	}
	return r;
}
long long getll(int a)
{
    
    
	long long r = 1;
	while(a--)r*=10;
	return r;
}
int main()
{
    
    
	int n,k;
	long long ans = 0;
	cin >> n >> k;
	for(int i = 0;i < n;i++)
	{
    
    
		cin >> a[i];
		long long p = 0,q = 1;
		while(p<10)
		{
    
    
			long long t = (a[i]*q)%k;
			mod[p][t]++;
			p++;
			q*=10;
		}
	}
	//cout << mod[1][0] << ' ' << mod[1][1];
	for(int i = 0;i < n;i++)
	{
    
    
		//cout << getl(a[i]) << ' ' << (k-a[i]%k)%k << endl;
		ans+=mod[getl(a[i])][(k-a[i]%k)%k];
		//cout << a[i]*getll(getl(a[i]))%k;
		if((a[i]*getll(getl(a[i])) + a[i])%k == 0)ans--;
	}
	cout << ans;
	return 0;
	
}

J network analysis

Solving through the union search set only needs to find the weight of each point at the end, so the union search set only needs to update each root value.
The specific method is to set up an increment array to save the increment value of the points in each union collection. Each time the collection is merged, the increment value of the root of the merged set minus the increment value of the root of the merged set , In this way, when calculating the weight of the point at the end, we only need to find the root from the bottom up and add the increment value each time to get the final weight of the point. When merging the collection, only the parent node of the root node is updated, the parent nodes of other nodes are still the root node, and the increment value is only updated to the root node. It can be analogized to generate a tree, and the weight of the leaf node is Root finding process.

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 10010;
int ans[maxn];
int add[maxn];
int fa[maxn];
int v[maxn];
int f(int i)
{
    
    
	if(fa[i]!=i)return f(fa[i]);
}
void uni(int a,int b)
{
    
    
	if(f(a) == f(b)) return;
	else
	{
    
    
		a = f(a),b = f(b);
		if(v[a]>=v[b])
		{
    
    
			add[b]-=add[a];
			fa[b] = a;
			v[a]+=v[b];
		}
		else
		{
    
    
			add[a]-=add[b];
			fa[a] = b;
			v[b]+=v[a];
		}
	}
}
int main()
{
    
    
	int n,m;
	int c = n;
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
    
    
		fa[i] = i;v[i] = 1;
	}
 	for(int i = 0;i < m;i++)
	{
    
    
		int a,b,c;
		cin >> a >> b >> c;
		if(a == 1)
		{
    
    
			uni(b,c);
		}
		else
		{
    
    
			add[f(b)]+=c;
		}
	}
	for(int i = 1;i <= n;i++)
	{
    
    
		int t = i;
		ans[i]+=add[i];
		while(fa[t]!=t)
		{
    
    
			ans[i]+=add[fa[t]];
			t=fa[t];
		}
	}
	for(int i = 1;i <= n;i++)
	cout << ans[i] << endl;
	return 0;
}

Title link: https://pan.baidu.com/s/1xcNT6pqKltR_WLhlep64OA
Extraction code: 5789
I have a private message and I will get it.

Guess you like

Origin blog.csdn.net/qq_39586345/article/details/107174706