Educational Codeforces Round 83 (ABCD)


Educational Codeforces Round 83 (Rated for Div. 2)


前言


比赛AC


A. Two Regular Polygons

简明题意

  • t组样例,每次给出nm(m<=n),问你正m边形的顶点是否能完全与正n边形重合

正文

  • 顶点完全重合的充要条件是m|n。只需要一次简单的判断就可以了。
  • 原因:直接在n边形上取点,我们可以选择每隔一个点取一个,隔两个,隔三个,隔k个…如果隔若干个点刚好能取到,那么n/k就是取到的点数,反过来就是直接判断是否有m|n

代码


B. Bogosort

简明题意

  • 给定n长的数组,需要你重新刚给这个数组排列,使得对任意的i,j,有 i < j j a j i a i i<j且j-a_j\not=i-a_i

正文

  • 注意到ij是升序的,现在有 a i i a_i-i ,那么把a数组降序排列就可以了,这样可以使得 a i i a_i-i 升序,就不会有相等的了。

代码

略。


C. Adding Powers

简明题意

  • 有一个n长的数组,给你一个k,现在有无限多个整数i(i>=0),你每次可以让数组的任意一位+= k i k^i (但相同的i只能用一次)
  • 现在给你一个数组和k,问你这个数组能不能由上面的方法构造出来。

正文

  • 看见 k i k^i 应该立马想到k进制了。那么我们可以直接把数组中的每一项都转换成k进制数,然后需要满足1个条件:
  • 1.所有的 k i k^i 中的i都应该不一样。这个直接数组判一下就行。
  • 满足了这个就yes,否则就no。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
#include<map>
#include<queue>
#include<string>
#include<vector>
using namespace std;

const int maxn = 100;

void solve()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n, k;
		int rec[100] = { 0 };
		cin >> n >> k;

		bool ok = 1;
		for (int i = 1; i <= n; i++)
		{
			long long t;
			cin >> t;
			if (!ok) continue;

			int w = 0;
			while (t)
			{
				w++;
				if (t%k == 1)
				{
					if (rec[w] == 1)
					{
						ok = 0;
						break;
					}
					else rec[w] = 1;
				}
				else if (t%k >= 2)
				{
					ok = 0;
					break;
				}
				t /= k;
			}
		}
		cout << (ok ? "YES" : "NO") << endl;
	}
}

int main()
{
	//freopen("Testin.txt", "r", stdin);
	solve();
	return 0;
}

赛后补题


D. Count the Arrays

简明题意

  • 计数题。计算满足某些要求的序列的数量。
  • 1.含有n个元素
  • 2.每个元素的大小在[1,m]
  • 3.这n个元素中只有两个是相同的,其他互相都不同
  • 4.存在一个i使得i前面的元素比它小,i后面的元素也比它小(严格小)

正文

  • 因为有两个数是相同的,所以满足要求的序列中,一定含有n-1个不同的元素。因此我们从先从m个数中选出n-1个,就是 C m n 1 C_{m}^{n-1 }
  • 再选一个数作为重复数,共有n-1种数,除了最大值不能重复,其他数都能重复,也就是有n-2种重复法。
  • 最后,数都选好了,我们要确定顺序。现在确定了n个数,这n个中有1个最大数,有2个重复数,剩下n-3个不一样的数。我们如果给这n-3个数排序,怎么排序呢?我们要把这n-3个数分成两部分,第一部分单调增,另一部分单调减,然后把最大数放在中间。剩下的2个相同数的位置就是固定的了。那么这n-3个数怎么分成两部分呢,这个就是 C n 3 0 + C n 3 1 + + C n 3 n 3 = 2 n 3 C_{n-3}^0+C_{n-3}^1+···+C_{n-3}^{n-3}=2^{n-3}
  • 根据乘法原理,把上面的乘起来,答案就是 C m n 1 ( n 2 ) 2 n 3 C_m^{n-1}*(n-2)*2^{n-3}

代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
#include<map>
#include<queue>
#include<cstdio>	
#include<map>
#include<vector>
#include<string>
using namespace std;

const int maxn = 1e5 + 10;
const int mod = 998244353;

int ksm(int a, int b)
{
	int ans = 1, base = a;
	while (b)
	{
		if (b & 1)
			ans = 1ll * ans * base % mod;
		b >>= 1;
		base = 1ll * base * base % mod;
	}
	return ans;
}

int C(int n, int m)
{
	int ans = 1;
	for (int i = 0; i < m; i++)
		ans = 1ll * ans * (n - i) % mod;

	int b = 1;
	for (int i = 1; i <= m; i++)
		b = 1ll * b * i % mod;

	return 1ll * ans * ksm(b, mod - 2) % mod;
}

void solve()
{
	int n, m;
	cin >> n >> m;
	if (n < 3)
	{
		cout << 0;
		return;
	}
	cout << 1ll * C(m, n - 1) * (n - 2) % mod * ksm(2, n - 3) % mod;
}

int main()
{
	//freopen("testin.txt", "r", stdin);
	solve();
	return 0;
}

简明题意

正文

代码


简明题意

正文

代码


总结

发布了122 篇原创文章 · 获赞 44 · 访问量 6972

猜你喜欢

转载自blog.csdn.net/weixin_42431507/article/details/104861479