Educational Codeforces Round 83(部分题解)

E d u c a t i o n a l   C o d e f o r c e s   R o u n d 83 Educational \ Codeforces \ Round 83 Educational Codeforces Round83(部分题解)

吐槽时间:

w z b l wzbl wzbl,我的 E E E y z c yzc yzc神仙 H a c k Hack Hack了,比较气愤 ( r k 94 − r k 428 ) (rk 94-rk 428) (rk94rk428)。啊啊啊!如果是 c f cf cf赛制就好了,为什么要是 a c m acm acm赛制啊。

A .   T w o R e g u l a r P o l y g o n s A.\ Two Regular Polygons A. TwoRegularPolygons

s b sb sb题,由于被 x g c xgc xgc干扰思绪停止。其实就是判断 m ∣ n m|n mn即可。

#include 
//#define int long long
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

int n,m,Q;

int main()
{
	Q=read();
	for (;Q--;)
	{
		n=read();
		m=read();
		if(n%m==0) printf("YES\n");
		else printf("NO\n");
	}
}

B .   B o g o s o r t B.\ Bogosort B. Bogosort

A A A同时提交,还算快。只要从大到小输出 a i a_i ai即可。

#include 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

int Q,a[111],n;

int main()
{
	Q=read();
	for (;Q--;)
	{
		n=read();
		for ( int i=1;i<=n;i++ ) a[i]=read();
		sort(a+1,a+n+1);
		for ( int i=n;i>=1;i-- ) printf("%d ",a[i]);
		cout<<endl;
	}
}
		

C .   A d d i n g P o w e r s C.\ Adding Powers C. AddingPowers

只要对于每一个数,拿出来分解出它关于 k k k 的幂次方的因数,并记录,看看这个因数前面有没有用过,用过的话就不行,或者分解完出现不是 k k k 的幂次方的因数。也是比较简单的,可以 w a wa wa了一发。

#include 
#define int long long 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

int n,m,Q,a[10005],ton[105];

inline int ksm(int x,int y)
{
	int ret=1ll;
	while(y)
	{
		if(y&1) ret=ret*x;
		x=x*x;
		y>>=1ll;
	}
	return ret;
}

signed main()
{
	Q=read();
	for (;Q--;)
	{
		n=read(),m=read();
		int las=0,gs=0;
		memset(ton,0,sizeof(ton));
		for ( int i=1;i<=n;i++ ) 
		{
			int x=read();
			int bit=0;
			while(x) ton[++bit]+=x%m,x/=m;
		}
		int i;
		for ( i=1;i<=70;i++ ) 
			if(ton[i]>1)
			{
				puts("NO");
				break;
			}
		if(i==71)puts("YES");
	}
}
			

D .   C o u n t t h e A r r a y s D. \ Count the Arrays D. CounttheArrays

一道找规律题,发现规律即可: ∑ i = 2 n − 1 C ( m , n − 1 ) ∗ ( n − 2 ) ∗ C ( n − 3 , i − 2 ) \sum_{i=2}^{n-1}C(m,n-1)*(n-2)*C(n-3,i-2) i=2n1C(m,n1)(n2)C(n3,i2)

然后组合数处理一波即可。

#include 
#define int long long 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}
const int N=1e6+5;
const int mod=998244353;
inline int ksm(int x,int y)
{
	int ret=1ll;
	while(y)
	{
		if(y&1) ret=ret*x%mod;
		x=x*x%mod;
		y>>=1ll;
	}
	return ret;
}



int n,m,jc[N],inv[N],ans;

inline int C(int x,int y)
{
	return jc[x]%mod*inv[y]%mod*inv[x-y]%mod;
}

signed main()
{
	n=read();
	m=read();
	jc[0]=inv[0]=1;
	for ( int i=1;i<=2e5;i++ ) jc[i]=jc[i-1]*i%mod;
	for ( int i=1;i<=2e5;i++ ) inv[i]=ksm(jc[i],mod-2)%mod;
	for ( int i=2;i<n;i++ ) 
		ans=(ans+C(m,n-1)*(n-2)%mod*C(n-3,i-2)%mod+mod)%mod;
	printf("%lld\n",ans);
	return 0;
}

E .   A r r a y S h r i n k i n g E. \ Array Shrinking E. ArrayShrinking

一道区间 D P DP DP题,可以参考类原题做法

然后就是区间 D P DP DP的普通操作 g i , j =   m i n ( g i , j , g i , k + g k , j ) g_{i,j}=\ min(g_{i,j},g_{i,k}+g_{k,j}) gi,j= min(gi,j,gi,k+gk,j),预处理看代码即可。

真的自闭:一开始 D P DP DP的循环第一层只有枚举到 1000 1000 1000,过于愚蠢被 y z c yzc yzc神仙 H a c k Hack Hack啦。。(无语 i n g ing ing

#include 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

const int N=505,M=1005;
int n,ans,f[N][M],dis[N][N];

signed main()
{
	n=read();
	for(int i=1,x;i<=n;i++) f[i][read()]=i+1;
	memset(dis,127/3,sizeof(dis));
	for( int j=2;j<=2000;j++ )
		for( int i=1;i<=n;i++ )
		{
			if(f[i][j]==0) f[i][j]=f[f[i][j-1]][j-1];
			if(f[i][j]>0) dis[i][f[i][j]]=1;
		}
	for( int i=1;i<=n;i++ ) dis[i][i+1]=1;
	for( int k=1;k<=n+1;k++ )
		for(int i=1;i<=n+1;i++) 
			if(i^k)
				for(int j=1;j<=n+1;j++) 
					if(j!=i&&j!=k)
						dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
	printf("%d\n",dis[1][n+1]);
}

F / G F/G F/G不会,先咕咕

但是开黑把 G G G过了,我谔谔

你可能感兴趣的:(codeforces,codeforces比赛)