CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes) 题解

A. Good Pairs

题意:在数组中找出两个数i,j,使得gif.latex?%5Cforall%201%20%5Cleqslant%20k%20%5Cleqslant%20n%20%2C%20%5Cleft%20%7C%20a_%7Bi%7D%20-%20a_%7Bk%7D%20%5Cright%20%7C%20+%20%5Cleft%20%7C%20a_%7Bj%7D%20-%20a_%7Bk%7D%20%5Cright%20%7C%20%3D%20%5Cleft%20%7C%20a_%7Bi%7D%20-%20a_%7Bj%7D%20%5Cright%20%7C

分析: 只需要找最大值和最小值的下标即可

code:

#include

using namespace std;

void solve() {
	int n; cin >> n;
	vector a(n);
	for (int &i : a) cin >> i;
	cout << max_element(a.begin(), a.end()) - a.begin() + 1<< " " << min_element(a.begin(), a.end()) - a.begin() + 1 << "\n";
}

int main() {
	int tt; cin >> tt;
	while (tt--) {
		solve();
	}



	return 0;
}

 

B. Subtract Operation

题意: 给定一个数组,每次可以从中选择一个数,令其他数减去这个数,并把选中的这个数删去,问最终能否得到数字k。

分析: 此操作不影响任意两数之差,所以我们只需要判断数组中是否有两个数的差等于k即可

code:

#include

using namespace std;

void solve() {
	int n, k; cin >> n >> k;
	map mp;
	for (int i = 1; i <= n; ++i) {
		int x; cin >> x;
		mp[x] = 1;
	}
	for (auto [a, b] : mp) {
		if (mp.count(a + k)) {
			cout << "YES\n";
			return ;
		}
	}
	cout << "NO\n";
}

int main() {
	int tt; cin >> tt;
	while (tt--) {
		solve();
	}



	return 0;
}

 

C. Make Equal With Mod

题意: 给定一个长度为n的数组,你可以选择一个数x >= 2并且将数组中的每个元素k变成 k mod x

若干次操作后,能否使得数组中各元素相等

分析: 可以从特殊情况来考虑,在mod的意义下,1和0这两个数比较特殊,故我们从这两个数开始考虑

如果数组中没有1,则一定能将所有数置0

如果数组中有1而且有0,则输出NO

现考虑将所有元素置1,对于数组中的任何一个数k,我们可以从大到小选择x = k - 1 ,这样就可以将数组全部置1了,如果有连个连续的自然数就不行了,因为他们的差始终为1

code:

#include

using namespace std;

void solve() {
	int n; cin >> n;
	map mp;
	for (int i = 1; i <= n; ++i) {
		int x; cin >> x;
		mp[x] = 1;
	}
	if (!mp.contains(1)) {
		cout << "YES\n";
		return ;
	} if (mp.contains(0)) {
		cout << "NO\n";
		return ;
	}

	for (auto [a, b] : mp) {
		if (mp.contains(a + 1)) {
			cout << "NO\n";
			return ;
		}
	}
	cout << "YES\n";
}

int main() {
	int tt; cin >> tt;
	while (tt--) {
		solve();
	}



	return 0;
}

 

D. K-good

题意: n能否分解为k个正整数的和,且这k个正整数对k的余数两两不相同

若n是k-good 则一定满足

  • n≥1+2+…+k=k(k+1)2n≥1+2+…+k=k(k+1)2.
  • n≡1+2+…+k≡k(k+1)2(modk)n≡1+2+…+k≡k(k+1)2(modk).

code:

 

#include

using namespace std;

void solve() {
	long long n; cin >> n;
	long long ans = 1;
	while (n % 2 == 0) {
		n /= 2;
		ans *= 2;
	}
	if (n == 1) {
		cout << "-1\n";
	} else {
		cout << min(n, 2 * ans) << "\n";
	}

}

int main() {
	int tt; cin >> tt;
	while (tt--) {
		solve();
	}



	return 0;
}

 

E. Equal Tree Sums

题意: 给出一棵树,请为每个结点赋点权,使得对于任意的 i ,删去点  i后,树分为若干连通块,每个连通块的点权和相等。

思路: 黑白染色,黑正白负,每个节点的绝对值为度数。

code:

#include

using namespace std;

void solve() {
	int n; cin >> n;
	vector G[n + 1];
	int ans[n + 1];
	for (int i = 1; i <= n - 1; ++i) {
		int x, y; cin >> x >> y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	function dfs = [&](int now, int fa, int col) {
		ans[now] = col * G[now].size();
		for (auto it : G[now]) {
			if (it != fa) {
				dfs(it, now, -col);
			}
		}
	};
	dfs(1, 1, 1);
	for (int i = 1; i <= n; ++i) {
		cout << ans[i] << " \n"[i == n];
	}
}

int main() {
	int tt; cin >> tt;
	while (tt--) {
		solve();
	}



	return 0;
}

 

 

你可能感兴趣的:(算法)