2023 The 6th Guangxi Undergraduate Programming Contest (warm-up competition) problem solving


Competition link, you can continue to submit code

The 6th Guangxi Undergraduate Programming Contest in 2023 (warm-up competition)

The questions are all from the original questions of last year's provincial competition

References

Zhihu: Some solutions to the fifth GXCPC Guangxi College Student Programming Competition (without CDK)

Question A will send sub-questions, skip


B bit operation lowbit function

The main idea of ​​the topic:

Perform an operation on a number (binary) and ask for the shortest operation steps to make it 0.
Operation mode: x+=lowbit(x) or x−=lowbit(x)

Problem-solving ideas:

After observation,
a single "1" can be converted to "0" only after one operation, that is, the
continuous "1" of x−=lowbit(x) can be converted to "0" only after two operations, such as
1111 -> x+=lowbit(x) -> 10000 -> x−=lowbit(x) -> 0

In order to handle it better (to avoid the need to add 0 when carrying to the first digit), you can reverse it first, and add two characters "00" at the end.

Then scan the string from left to right. If a character is scanned as '1', the character to the right of it is checked.
If the character on the right is '0', it means that this is an independent "1", and the count is increased by one;
if the character on the right is also '1', it means that this is a continuous "11", and the first Each '1' is changed to '0', and the previous '1' is changed to '0', until a '0' is encountered, and the last '0' is changed to '1'. Then go back one space and continue scanning.

Reference code c++

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

signed main() {
//	加快输入输出速度,常用方法
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	string s;
	cin >> s;
	reverse(s.begin(), s.end());
	s += "00";
	int cnt = 0, n = s.size();
	for (int i = 0; i < n; i++) {
		if (s[i] == '1') {
			if (i == n - 1 || s[i + 1] == '0')
				cnt++;
			else {
				while (i < n - 1 && s[i] == '1')
					s[i++] = '0';
				s[i] = '1';
				i--;
				cnt++;
			}
		}
	}
	cout << cnt << endl;
	return 0;
}

C homework

The main idea of ​​the topic:

There are many assignments to be written, each with a different word count (time required). But you can write one copy first, and then copy it for others. Of course, it takes different time to copy different assignments.

Problem-solving ideas:

First of all, we must at least write the most words, and we can use copy and paste to solve the rest.

But it doesn't mean that we finish the most homework first. For example, the three homework numbers are 100, 200, and 300, and the corresponding copying time is 99, 199, and 1. So obviously we write 200 words first, then copy them to homework 1 and 3, and finally make up the missing words in homework 3 to save time.

Since the number of words we want to write has been fixed, we can know the preliminary time, and then only the first copy cannot be pasted, so we choose the one that takes the most time to copy for the first assignment.

That is, the total time is: the maximum number of words + the sum of other copying times after the maximum copying time is removed.

Reference code c++

#include <iostream>
#include <vector>
using namespace std;
#define endl '\n'
#define int ll
typedef long long ll;

signed main() {
//	加快输入输出速度,常用方法
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int n, cnt = 0, ans = 0;
	cin >> n;
	vector<int>a(n), b(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		cnt = max(cnt, a[i]);
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
		cnt += b[i];
		ans = max(ans, b[i]);
	}
	cout << cnt - ans;
	return 0;
}

D no jealousy

The main idea of ​​the topic:

There are two people, and the value of the same commodity is different in their eyes. It is necessary to compare the value of one's own things with the value of the other party's things among the first i items.

Problem-solving ideas:

The question is very long, but it is a sign-in question (as the big guy on the Internet said).

Record the maximum value of your own items on both sides in your own eyes and the maximum value in the eyes of the opposite party, and the two items that the opposite party thinks my value is the largest and the smallest.

  • As long as both sides think their things are of the highest value, EF will be output.
  • If the value of the opposite item minus the smallest item is smaller than mine, output EFX.
  • If the value of the opposite item minus the largest item is smaller than mine, output EF! .
  • In other cases, output E.

It is much more convenient to use pair processing.

Pay attention to optimization, otherwise you may not be able to pass.

Reference code c++

Use C++ (g++ 7.5.0) to submit code, C++ (clang++ 11.0.1) may have problems

#include <iostream>
using namespace std;
// 这行要写,不然可能过不去
#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;

signed main() {
//	加快输入输出速度,常用方法
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	//max表示对面认为我的价值最高的物品,min表示对面认为我的价值最低的物品
	int n, a, b, c, maxx = 0, maxy = 0, minx = 1e9, miny = 1e9;
	//first表示自己拥有的自己眼里物品总价值,second表示自己拥有的对面眼里物品总价值
	PII x, y;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a >> b >> c;
		if (c == 0) { // 物品属于第一个人
			x.first += a;
			x.second += b;
			maxx = max(maxx, b);
			minx = min(minx, b);
		} else { // 物品属于第二个人
			y.first += b;
			y.second += a;
			maxy = max(maxy, a);
			miny = min(miny, a);
		}
//		对应四种情况
		if (x.first >= y.second && y.first >= x.second) {
			cout << "EF" << endl;
		} else if (x.first >= y.second - miny && y.first >= x.second - minx) {
			cout << "EFX" << endl;
		} else if (x.first >= y.second - maxy && y.first >= x.second - maxx) {
			cout << "EF1" << endl;
		} else
			cout << "E" << endl;
	}
	return 0;
}

The following is the translation of Question D:

D not jealous

topic description

This question is a fundamental problem in economics and computer science: how to distribute goods fairly to competing agents.

The problem assumes that there is a set M containing m items, and the goal is to distribute these items among n agents in a fair manner.

One of the concepts of "fairness" is not to be jealous. Specifically, if the value of agent i's item combination Xj owned by agent j is higher than the value of its own item combination Xi, then agent i is said to be jealous of agent j.

Among them, each agent is interested in each item j, and has a value wi for it, and is also interested in a set of items S, and expresses the sum of the values ​​of all items in it as Wi(S).

Allocation is the process of partitioning M into disjoint subsets X1, ..., Xn, where Xi is the set of items assigned to agent i.

This question involves three allocation methods: EF (envy of zero), EFX (envy of any item), EF1 (envy of one item). In the first most preferred and best allocation method EF, no one agent can be jealous of another agent; in the second allocation method EFX, agent i can be jealous of agent j, but as long as the agent i This envy disappears when any item is removed from the set of items owned by person j; in the third assignment EF1, agent i can also be jealous of agent j, but as long as Remove any one item from the set and the envy goes away.

In this problem, consider only the case of two agents, Colin and Eva. To start, none of them have any items. Then perform m operations, and each operation provides three values ​​ci, ei and bi, representing the value of the item from the perspectives of Colin and Eva, and whether the item is assigned to Colin or Eva. After each operation, it is necessary to judge the priority of the current allocation method. The highest is EF, followed by EFX, and then EF1, if not satisfied, the worst is envy.

enter description

The first line contains an integer m (1 <= m <= 10^6).

In the next m lines, each line contains three integers ci, ei (1 <= ci,ei <= 10^6) and bi (bi∈{0,1}), which represent Colin and Eva’s Like value and whether to assign the item to Colin or Eva.

output description

After each operation, output a line:

  • If the current allocation method is "EF", then output "EF";

  • Otherwise, if the current allocation method is "EFX", then output "EFX";

  • Otherwise, if the current allocation method is "EF1", then output "EF1";

  • Otherwise output "E".

Example 1

enter

5
5 2 0
5 2 1
2 2 0
9 2 1
9 2 1

output

EFX
EF
EFX
EF1
E

Guess you like

Origin blog.csdn.net/weixin_45940369/article/details/131024684