Question solution of Nanhua University level 19 soft Zhuo trial [code sentence by sentence analysis]

Posted by NoMansLand on Thu, 03 Mar 2022 14:04:41 +0100

First of all, the official solution of last year is here. You can have a look 19 official explanation of the selection of ruozhuo
In my problem solution, I will analyze the code of problem C sentence by sentence as far as I can. Problem C has not been figured out yet
Soft Zhuo selects A Taoge to supplement the spirit
Soft Zhuo selection A
This question does not test any algorithm, but it is a simulation question to test the foundation, but the meaning of the question is indeed a little windy. Writing this problem still needs a relatively solid basic skill of c + +

#include<iostream>
#define ll long long
using namespace std;

int main()
{
	ll t = 0;//According to the meaning of the question, 10% of the data is in the longlong class, so the answer needs to use longlong
	cin >> t;//t queries
	while (t--)
	{
		ll a, b, c, d,ans=0;
		cin >> a >> b >> c >> d;//Definition and input
		if (a <= b)//If you need less sleep than the first alarm clock, wake up after the first alarm clock rings
		{
			cout << b << endl;//Output answer
			continue;//Enter the next cycle
		}
		else
		{
			if (c <= d)//If you fall asleep again longer than the bell time, you will never get out of bed again
			{
				cout << "-1" << endl;//Output - 1 according to the meaning of the question
				continue;
			}
			else//This is the case when you can get up
			{
				ans = b;//First initialize the answer to the time when the first alarm rings
				a -= b;//The update also requires sleep time
				ll k = c - d;//k represents the time to fall asleep, that is, the alarm interval minus the time required to fall asleep
				if (a % k == 0)//Calculate how many times the alarm will ring before you get up
				{
					ans += c * (a / k);//How many times does the answer take
				}
				else//It should be noted here that even if you have enough sleep time, you won't get up if the alarm doesn't ring, so you need (a+k+1)
				{
					ans += c * ((a / k) + 1);//Answer update
				}
				cout << ans << endl;//Output answer
			}
		}
	}
	return 0;
}


Soft B suffix zero count
Soft Zhuo selection B
This is a math problem. Many students may calculate this number and then see how many suffixes are zero. However, it should be noted that the limit of longlong data type is the 18th power of 10. If this number is calculated completely, it will certainly exceed this value, so we need to use other methods to solve this problem. Of course, You can get part of the score directly. A real game can get some points like this
Idea: first of all, if there is 0, there must be 10 in multiplication. Only when there is a multiple of 10 in multiplication can there be 0. For example, 45 equals 20, in fact, 225 = 210 equals 20. Then let's look at 10. Only 25 equals 10, and 103 = 20 can be regarded as 253. Then the problem turns to how many 2 and 5 your data can be decomposed into, such as 10, 2, 8, 5, A total of 5 2, 2 5, can come up with 2 * 5, then the answer is 2

#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
ll x, y;//Used to record how many 2 and 5 appear in total
ll a[100000];//Used to record data
void fun(ll t)//A function that can divide t by 2 at most several times is implemented recursively
{
	if (t % 2 == 0)
	{
		x++;
		fun(t / 2);
	}
	else
		return;
}
void fun2(ll t)//A function that can divide t by 2 at most several times is implemented recursively
{
	if (t % 5 == 0)
	{
		y++;
		fun2(t / 5);
	}
	else
		return;
}
int main()
{
	ll n;
	cin >> n;
	for (ll i = 0; i < n; i++)
	{
		cin >> a[i];
		if (a[i] % 2 == 0)
		{
			fun(a[i]);//It is used to calculate the number of 2. Because x is a global variable, it will not return to zero every time because of the loop
		}
		if (a[i] % 5 == 0)
		{
			fun2(a[i]);//Used to calculate how many 5
		}
	}
	cout << min(x, y);//The smaller of the output x, y is the correct answer
	return 0;
}

Soft Zhuo selects C tower son to calculate the probability
Soft Zhuo selection C
Last year's most difficult question was one that no senior student wrote last year... The author hasn't written it yet... So if you are interested, you can see the official solution written by brother Tazi below

Tazigo said:
This is an original problem adapted from P250 after class exercise 12.1 of discrete mathematics
It is not difficult to find: This is a classical probability, and the denominator is determined. It mainly calculates the numerator, that is, the number of schemes that meet the requirements
Solution with 20 points: triple cycle, violence statistics, all legal schemes Complexity O(n^3)
Solution with 40 points: Optimization: triple cycle. The innermost cycle is determined according to the value of the outer double cycle. The step is m and the complexity is
O(\frac{n^3}{m} )
Solution with 70 points: application of congruence
First, thoroughly understand the solution of the problem in the book:
https://www.zybang.com/question/47028159d760daa405307dd3158dd42e.html
In this way, the upper bound of our triple cycle is no longer n, but m. According to the simple counting principle, count the number of numbers in three congruence classes each time to find the combination number.
In the inner layer, I use map to store I, J and K, but since only three elements are stored at a time, the complexity of this part is constant and can be ignored
It is not difficult to find that the number of combinations in the inner layer is equal to 3, which is also a constant coefficient and is ignored
So total complexity: O(m^3)
Solution with 100 points:
According to the congruence relation identity (I, J and K are cyclic variables of three-layer cycle respectively)
The k of the innermost loop can be calculated according to the I, J, O (1) determined by the outer layer, and the innermost loop can be optimized
Reducing the complexity to O(m^2) can completely pass the problem.

#include<bits/stdc++. h> / / Universal header file
using namespace std;
const int maxn = 1e5 + 5;
#define ll long long
ll C(ll a , ll b)
{
    if (a < b) return 0;
    if (b == 0 || b == a) return 1;
    if (b > a - b) b = a - b;
    ll up = 1 , down = 1;
    for (int i = 0 ; i < b ; i++){
        up = up * (a - i);
        down = down * (b - i);
    }
    return up / down;
}
ll R[maxn];
map <ll,ll> book;
int main()
{
    ll n , m ; cin >> n >> m;
    for (int i = 1 ; i <= n ; i++)
        R[i%m]++;
    ll cnt = 0 , res = 1;
    for (int i = 0 ; i < m ; i++){
        for (int j = i ; j < m ; j++){
            ll k = (m - i - j + 3 * m)%m;
            if (k < j) continue;
            if ((i + j + k)%m == 0){
                book.clear();
                book[i]++ , book[j]++ , book[k]++;
                res = 1;
                for (auto g : book) {
                    res *= C(R[g.first] , g.second);
                }
                cnt += res;
            }
        }
    }
    ll g = __gcd(cnt , C(n , 3));
    cout << cnt / g << "/" << C(n , 3) / g << endl;
    return 0;
}

Soft Zhuo selects D junior y to learn mathematics
Soft Zhuo selection D
It's still a thinking problem. It's not difficult to think of it, but it's hard to think of it. Think of it and test your basic skills

#include<iostream>
#define ll long long
using namespace std;

int main()
{
	ll n;
	cin >> n;
	if (n<10)//If the number is less than 10, make a special judgment and output the number plus 10
	{
		cout << 10+n;
		return 0;
	}
	else
	{
	    /*In order to decompose this number into factors, we must find it from 9 to 1, because we have 8 = 2 * 2 * 2. Of course, it is better to write three 2 in the result than an 8*/
		int x9 = 0;
		while (n % 9 == 0) { x9++; n /= 9; }
		int x8 = 0;
		while (n % 8 == 0) { x8++; n /= 8; }
		int x7 = 0;
		while (n % 7 == 0) { x7++; n /= 7; }
		int x6 = 0;
		while (n % 6 == 0) { x6++; n /= 6; }
		int x5 = 0;
		while (n % 5 == 0) { x5++; n /= 5; }
		int x4 = 0;
		while (n % 4 == 0) { x4++; n /= 4; }
		int x3 = 0;
		while (n % 3 == 0) { x3++; n /= 3; }
		int x2 = 0;
		while (n % 2 == 0) { x2++; n /= 2; }
		if (n != 1)//If this number is a prime number greater than 10, then the above x1 to x9 are all 0, otherwise it is decomposed to this step, and n must be equal to 1
		{
			cout << -1;//Output - 1, no answer
			return 0;
		}

        /*After that, just output these factors from small to large, so that the multiplication of each digit of the sub output number must be equal to the original number*/
		for (int i = 0; i < x2; i++)
		{
			cout << 2;
		}
		for (int i = 0; i < x3; i++)
		{
			cout << 3;
		}
		for (int i = 0; i < x4; i++)
		{
			cout << 4;
		}
		for (int i = 0; i < x5; i++)
		{
			cout << 5;
		}
		for (int i = 0; i < x6; i++)
		{
			cout << 6;
		}
		for (int i = 0; i < x7; i++)
		{
			cout << 7;
		}
		for (int i = 0; i < x8; i++)
		{
			cout << 8;
		}
		for (int i = 0; i < x9; i++)
		{
			cout << 9;
		}
	}
	return 0;
}

Ruo Zhuo selects E xiaO y to go up the stairs
Soft Zhuo selection E
If the problem is a dynamic programming problem, you can't find the law of the algorithm. If the problem is a dynamic programming problem, you can't find the law of the algorithm. However, for students who are skilled in dynamic programming, this problem is actually very simple. Due to the limited space, we will not introduce what is dynamic programming algorithm here. If you are interested, you can search and learn on csdn

#include<iostream>
#define ll long long
using namespace std;
ll q = 1e9 + 7;
int main()
{
	int n, k;
	ll dp[101];
	dp[0] = 1;//The scheme for climbing the stairs on the 0th floor is 1
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		dp[i] = 0;
		for (int j = 1; j <= k && i - j >= 0; j++)
		{
			dp[i] = ((dp[i] % q) + (dp[i - j] % q)) % q;
			/*According to the transfer equation, the number of schemes going up to each i-storey staircase is the sum of the number of schemes from i-1 to i-k floors*/
		}
	}
	cout << dp[n];//Number of schemes output to layer n
	return 0;
}

Soft Zhuo selects F Jerry's 2020
Soft Zhuo selection F
Non algorithmic questions, basic questions, examine the processing and use of strings. It examines the basic skills of the code.

#include<iostream>
#include<string>
#define ll long long
using namespace std;

int main()
{
	string a;
	string b="";//Define an empty string
	int ans = 0;//answer
	cin >> a;//String input
	for (int i = 0; i < a.size(); i++)//Traverse a string, delete characters other than '2' and '0', and store them in b
	{
		if (a[i] == '2' || a[i] == '0')
		{
			b += a[i];
		}
	}
	
	int t = 0;//t here stands for the number of '2020'
	for (int i = 0; i < b.size(); i++)
	{
		if (b[i] == '2' && t == 0)
		{
			b[i] = 'a';
			t++;
		}
		if (b[i] == '0' && t == 1)
		{
			b[i] = 'a';
			t++;
		}
		if (b[i] == '2' && t == 2)
		{
			b[i] = 'a';
			t++;
		}
		if (b[i] == '0' && t == 3)
		{
			b[i] = 'a';
			t = 0;
			ans++;
		}
	}
	cout << ans;//Finally, output the answer
	return 0;
}

Author: Avalon Demerzel, I hope this blog can help you

Topics: Algorithm Dynamic Programming