Educational Codeforces Round 83 (Rated for Div. 2)

A.Two Regular Polygons

题解

这个结论很好猜吧,肯定是倍数关系啦。
要证明的话,你就在那个\(n\) 边形的每一条边都扣出\(n/m\) 个角就可以了

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int T,n,m; 
int main()
{
	T=read();
	while(T--)
	{	
		n=read();m=read();
		if(n%m==0)puts("YES");
		else puts("NO");
	}
	return 0;
}

B.Bogosort

题解

既然是个构造,让\(j-a_j≠i-a_i\),那么由于第一项单增,我们只需要让\(a_i\) 递减排列就不可能出现相等情况了

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=110;
int T,n,a[maxn],b[maxn];
int main()
{
	T=read();
	while(T--)
	{
		n=read();
		for(int i=1;i<=n;i++)a[i]=read();
		sort(a+1,a+n+1);
		for(int i=n;i>=2;i--)printf("%d ",a[i]);
		printf("%d\n",a[1]);
	}
	return 0;
}

C.Adding Powers

题解

把每个数拆成\(k\) 进制。依题意,每一位至多是1,否则就不行。

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline LL read()
{
	LL x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int T,n,k,add[70];
LL a;
int main()
{
	T=read();
	while(T--)
	{
		mem(add,0);
		n=read();k=read();
		bool ok=0;
		for(int i=0;i<n;i++)
		{
			a=read();
			LL tmp=a;
			int j=0;
			while(tmp)
			{
				add[j]+=(tmp%k);
				if(add[j]>1){ok=1;break;}
				j++;
				tmp=tmp/k;
			}	
		}
		if(!ok)puts("YES");
		else puts("NO");
		
	}
	return 0;
}

D.Count the Arrays

题解

结论题
最多只能有两个数相等,所以不考虑重复的,有\(n-1\) 个数,从\(m\) 个数里选\(n-1\) 个,有\(C^{n-1}_m\) 种,然后最大的数当峰值,将剩下\(n-2\) 个数,分成两组一左一右,又有\(2^{n-2}\) 种,最后把重复的再算上,乘以一个\(n-2\) 就好了 ,再添加重复元素的时候需要注意,会产生多一倍的重复情况,例如\((1,2|3,1)\) 可以由\((1,2|3)\) 复制一个1以及\((2|3,1)\) 复制一个1获得,所以需要再除以2。
答案为\(C^{n-1}_m*(n-2)*2^{n-3}\)
需要特判\(n=2\)的情况(我还因此炸了两次)
考完才发现没有必要写快速幂

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int MOD=998244353;
int n,m;
LL inv[200010];
LL C(int n,int m)
{
	LL res=1;
	for(int i=1;i<=m;i++)res=(res*(LL)(n-i+1)%MOD*inv[i])%MOD;
	return res;
}
LL quickpow(LL a,int N)
{
    LL res=1;
    while(N)
    {
        if(N&1)res=(res*a)%MOD;
        a=a*a%MOD;
        N>>=1;
    }
    return res;
} 
int main()
{
	inv[1]=1;
    for(int i=2;i<=200000;i++)inv[i]=((LL)(MOD-MOD/i)*(LL)inv[MOD%i])%MOD;
	n=read();m=read();
	if(n==2)printf("%d\n",0);
	else printf("%lld\n",C(m,n-1)*quickpow(2,n-3)%MOD*(LL)(n-2)%MOD);
	return 0;
}

E.Array Shrinkin

题解

\(dp[i][j]\) 表示区间\([i,j]\) 最后能化成什么数,这个可以在\(O(n^3)\) 时间内解决,然后最后线段覆盖求最小值即可。

#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int maxn=510;
int n,a[maxn],dp[maxn][maxn],vis[maxn][maxn],f[maxn];
int DP(int L,int R)
{
	if(vis[L][R])return dp[L][R];
	vis[L][R]=1;
	int &res=dp[L][R];
	if(R<L)return -1;
	if(R==L)return res=a[L];
	for(int i=L;i<R;i++)
		if(DP(L,i)==DP(i+1,R) && DP(L,i)!=-1)return res=DP(L,i)+1;
	return res;
}
int main()
{
	mem(dp,-1);
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	DP(1,n);
	mem(f,42);
	f[0]=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			if(dp[j][i]!=-1)f[i]=min(f[i],f[j-1]+1);
	printf("%d\n",f[n]);
	return 0;
}

事后补题

F. Attack on Red Kingdom

题解

一定会来的
博弈论。。。有点害怕

废话

posted @ 2020-03-10 01:02  小飞淙的云端  阅读(618)  评论(0编辑  收藏  举报