Educational Codeforces Round 83 (Rated for Div. 2) A、B、C、D

比赛传送门

A. Two Regular Polygons

题意:给你两个正多边形的边数,问第二个正多边形能不能嵌套在第一个正多边形内
1.顶点必须对顶点 2.两个正多边形中心重合

题解:如果第一个正多边形的边数能整除第二个正多边形的条数 就可以满足嵌套

code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	ll n;
	cin>>n;
	while(n--)
	{
		ll n,m;
		cin>>n>>m;
		if(n%m==0)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}

B. Bogosort

题意:给你一个数组a,当 i<j时 满足 j - a[j] ≠ i - a[i] ,让你写出一个满足的数组序列

题解:下标是从小到大的,我们把序列从大到小排序,这样 下标 - 数组的值 永远不会相等,可以这样想,下标是从最小开始,数组从最大开始,差值肯定是最下的,遍历数组肯定差值会单调递增的。

code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[110];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	ll t;
	cin>>t;
	while(t--)
	{
		ll n;
		cin>>n;
		for(int i=0;i<n;i++)
			cin>>a[i];
		sort(a,a+n);
		for(int i=n-1;i>=0;i--)
			cout<<a[i]<<" ";
		cout<<'\n';
	}
	return 0;
}

C. Adding Powers

题意:给你一个n、k和一个num数组,让你从一个全为0的数组走i步能不能得到num数组:
对于第i步 1.走 任意给一个数 增加k^i
2.不走 不操作任何数

扫描二维码关注公众号,回复: 9863319 查看本文章

题解:看到k^ i 很敏感的想到了k进制数的第i位为1 , 每一步只能走1次,所以k^i只能任意增加1次。
把num数组的所有数转化成k进制,num数组的所有数的k进制数的每一个第j位(0<=j<=最大位数)总和最大为1(保证只走1次或不走,保证他只增加k^i )可以满足题意输出YES ,否则输出NO

code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[110];
ll num[110],vis[110];
void tranf(ll n,ll r)
{
 	for(ll i=0;i<55;i++)       
 	{
	  	a[i]=(ll)n%(ll)r;
	  	n/=(ll)r;
	  	if(n==0)
	  	{
	  		break;
		}
 	} 
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	ll t;
	cin>>t;
	while(t--)
	{
		ll n,k,o=0;
		cin>>n>>k;
		for(ll j=0;j<=55;j++)
			vis[j]=0;
		for(ll i=0;i<n;i++)
			cin>>num[i];
		ll p=0;
		for(ll i=0;i<n;i++)
		{	
			for(int q=0;q<55;q++)
				a[q]=0;
			if(p)
				break;
			tranf((ll)num[i],k);
			for(ll j=0;j<55;j++)
			{
				if(a[j])
				{
					vis[j]+=a[j];
					if(vis[j]>1)
					{
						p=1;
						break;
					}
				}	
			} 
		}
		if(p)	cout<<"NO"<<endl;
		else	cout<<"YES"<<endl;
	}
	return 0;
}

D. Count the Arrays

题意: 给你一个n和m,让你从[1,m]里任意挑选数,组成长度为n的数组kk
数组kk满足 1.有且仅由1对相同的数
2.第i个数为最大值,i前面的所有数严格递增,i后面的所有数严格递减。

题解: C( m , n-1 )* (n-2) * 2^(n-3)

长度为n的数组他有n-1个不同的数(因为条件1、2限制),所以我们要在m个数里挑选数n-1个不同的数来组成长度n,-------> C( m , n-1 )

条件1的限制,n-1个数里肯定会有一个最大值,这个就是数组kk的第i位,剩下的n-2个数每一位都有可能出现一个跟他相同的数组成长度为n的数组。---->C( m , n-1 )* (n-2)

条件2,我们已经把最大值和一对相同的数安排好位置(一对相同的数在最大值的两侧),剩下n-3个数该怎么排位置呢? 每个数都可以放在最大值的左侧或右侧,有2种选择,n-3个数不就是 2^(n-3) 种位置!-------> C( m , n-1 )* (n-2) * 2^(n-3)

code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=998244353;
ll f[maxn];
ll quick_pow(ll a,ll b)
{
	ll temp=a%mod,ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*temp)%mod;
		temp=(temp*temp)%mod;
		b>>=1;
	}
	return ans%mod;
}
ll ni(ll a)
{
	return quick_pow(a,mod-2);
}
void pre()
{
	f[0]=1;
	for(int i=1;i<maxn;i++)
	{
		f[i]=(f[i-1]*i)%mod;
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	pre();
	ll n,m;
	cin>>n>>m;
	if(n==2)
		cout<<0<<endl;
	else
		cout<<((f[m]*ni(f[n-1]%mod*f[m-n+1])%mod*(n-2))%mod*quick_pow(2,n-3))%mod<<'\n';
	return 0;
}
发布了88 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43667611/article/details/104794002