First Problem Solution of ACM Summer Training in Inner Mongolia (Primary Group)

Posted by shatner on Fri, 26 Jul 2019 14:49:43 +0200

 

List of topics:

Problem A Miss Sister's Programming Questions

Problem B A's brushing exercises

Problem C Small A origami crane

Problem D Little A plays games with little sister

Problem E Small A earns bonuses

Problem F Little A and Little Sister Paint the Balloon

Problem G Little A's Date

Questions on Programming of Miss Problem A

  • Main Algorithms: Violence Simulation
  • Solution: Four for loops can be simulated directly.
  • Note: The total number should be long, and it may explode int.
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;
const int MAX = 500 + 5;

int a[MAX];

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	ll sum = 0;
	for (int i = 0; i < n; i++) {
		for (int j = i + 1; j < n; j++) {
			if (a[i] >= a[j])
				continue;
			for (int k = j + 1; k < n; k++) {
				if (a[k] >= a[j])
					continue;
				for (int l = k + 1; l < n; l++) {
					if (a[i] < a[k] && a[k] < a[j] && a[j] < a[l])
						sum++;
				}
			}
		}
	}
	cout << sum << endl;
	return 0;
}

Problem B A's brushing exercises

  • Main Algorithms: Structural Sorting, Greed
  • Ideas for problem solving: bi means fatigue value, AI means the time it takes to solve a problem, giving priority to subjects with high fatigue value and less time, that is, greedy strategy is giving priority to subjects with large bi / ai. After the structure is arranged, the fatigue value of each problem is calculated before it is solved, and the total fatigue value is calculated finally.
  • Note: Median and final values need to be long, otherwise it may explode int.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX = 100000 + 5;


struct Node {
	int a;
	int b;
	long long int sum;
};

Node node[MAX];

bool cmp(Node x, Node y) {
	return (x.b * 1.0 / x.a) > (y.b * 1.0 / y.a);
}


int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> node[i].a >> node[i].b;
	}
	sort(node, node + n, cmp);
	node[n - 1].sum = node[n - 1].b;
	for (int i = n - 2; i >= 0; i--) {
		node[i].sum += node[i + 1].sum + node[i].b;
	}
	long long int cnt = 0; 
	for (int i = 1; i < n; i++) {
		cnt += node[i - 1].a * node[i].sum;
	}
	cout << cnt << endl;
	return 0;
}

Problem C Small A Origami Crane

  • Major Algorithms: None
  • Solution: Simulations will do.
  • Note: Pay attention to the parity of columns.
#include <iostream>
#include <cstring>
using namespace std;

int main() {
	int t;
	cin >> t;
	while (t--) {
		int n, m;
		cin >> n >> m;
		if (m % 2 == 1) {
			cout << m * n - 2 << endl;
		}
		else {
			cout << (m - 1)  * n - 1 << endl;
		}
	}
	
	return 0;
}

Problem D. A. Plays games with her sister

  • Main Algorithms: Game

  • Ideas for solving problems:

    Since m is an even number, it is advisable to discuss it in different categories:

    1. All cards can be flipped directly in one round (n=m). Obviously, small A can win and output No.

    2. You can't flip all cards directly in a round, because m is even, so you only need to discuss the parity of n.

    (1) n is an odd number of rounds at the end of which all cards face up on the opposite side can be equivalent to all cards being turned odd number times. Assuming that it can be achieved, then the total number of turns after the turn must be odd (because the sum of odd numbers is odd), but m is even, even if it is not bad, no matter how many turns are turned, the total number of turns must be even, so in this case, small A can not win the game. The output is Yes

    (2) n is even

    Similarly, all cards must be reversed odd times when they are finished, but n is even, so the total number of reversals must be even. Without being damaged, it is possible to complete at least. But except for the case of n=m, as long as they are damaged immediately after the first round, no matter which card is reversed, the total number will be made. The number of flips has changed from always even to always odd, which is the same as when n is odd. A can't win the game. The answer is Yes.

    Conclusion: When n=m, the answer is No, otherwise the answer is Yes.

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

int main() {
	int t;
	cin >> t;
	int n, m;
	while (t--) {
		cin >> n >> m;
		if (n == m) {
			cout << "No" << endl;
 		}
		else cout << "Yes" << endl;
	}
	return 0;
}

Problem E Little A Earns Bonus

  • Main Algorithms: and Search Sets
  • Solution: For each node must have a fixed ancestor, for all points with a father array to record his ancestors. Finally, an array C is used to record how many thieves there are at the end of the ancestor point. Then, the array C is sorted and the first M is the answer.
  • Note: The last burglar to be caught will use long-term storage, otherwise it will explode int.
  •  
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int MAX = 100000 + 5;

int father[MAX];
int a[MAX];
int b[MAX];
ll c[MAX];

bool cmp(ll a, ll b) {
	return a > b;
}

int find(int u) {
	return u == father[u] ? u : father[u] = find(father[u]);
}

void merge(int u, int v) {
	father[find(u)] = find(v);
}

int main() {
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= n; i++) {
		cin >> b[i];
	}
	for (int i = 0; i <= n; i++) {
		father[i] = i;
	}
	for (int i = 1; i <= n; i++) {
		merge(i, b[i]);
	}
	for (int i = 1; i <= n; i++) {
		find(i);
		c[father[i]] += a[i];
	}
	sort(c, c + MAX, cmp);
	ll cnt = 0;
	for (int i = 0; i < m; i++) {
		cnt += c[i];
	}
	cout << cnt << endl;
	return 0;
}

Problem F, A and Sister Paint the Balloon

- Major Algorithms: Number Theory (Combinatorial Mathematics)

- Solution: The way to make children happy is to paint balloons with different colors. That is, the first balloon has m colors, and the second n-1 balloon has m-1 colors. Even if children are happy, there are m*(m - 1)^(n-1) coloring methods.

- Note: Because the data is too large, a dichotomous fast power is needed.

#include <iostream>
using namespace std;

typedef long long ll;

const ll mod = 1000000000 + 7;

ll pow_mod(ll a, ll b) {
	ll ret = 1;
	while (b) {
		if (b & 1) ret = (ret * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	}
	return ret % mod;
}

int main() {
	ll n, m;
	cin >> n >> m;
	cout << (pow_mod(m - 1, n - 1) * m) % mod << endl;
	return 0;
}

Problem G Little A's Appointment

- Main Algorithms: Game

- Solution: At the beginning, from right to left, the leftmost string is 1 when the evil dragon is cut off. We let the evil dragon grow on the leftmost side is 1. When the good dragon is cut off is 0, we let it be generated randomly. In a limited number of times, the whole string can be changed to 1. Then cut off each 1 from right to left, add 0 to the left, and eventually turn into a 000... 000 string.

CONCLUSION: For any 01 string, we can turn it into 00... 000 string, then output "xiao A nb" to pass this topic.
#include<iostream>
#include<string>
using namespace std;

int main(){
    int t;
    cin >> t;
    while(t--){
        string s;
        cin >> s;
        cout << "xiao A nb" << endl;
    }
}

Topics: Programming less