比赛链接:Educational Codeforces Round 83 (Rated for Div. 2)
A. Two Regular Polygons
分析:判断是否倍数;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
const int mod=1e9+7;
const ll INF=1e18;
void rua()
{
int n,m;scanf("%d%d",&n,&m);
if(n%m==0) printf("YES\n");
else printf("NO\n");
}
int main()
{
int t;scanf("%d",&t);
while(t--) rua();
return 0;
}
B. Bogosort
分析:降序排序,越靠前的减数尽可能小,被减数尽可能大;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
const int mod=1e9+7;
const ll INF=1e18;
int a[maxn];
void rua()
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=n;i>0;i--) printf("%d ",a[i]);
printf("\n");
}
int main()
{
int t;scanf("%d",&t);
while(t--) rua();
return 0;
}
C. Adding Powers
题意:第i次操作可以给任意位置加上0或k^i,是否可以构成题给序列;
分析:check出每个数由k的几次构成并计数,次数不能超过1;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
const int mod=1e9+7;
const ll INF=1e18;
ll a[maxn];
int cnt[107];
void rua()
{
int n,k;scanf("%d%d",&n,&k);
for(int i=0;i<=100;i++) cnt[i]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]==0) continue;
if(a[i]==1) {cnt[0]++;continue;}
ll x=a[i],tmp=1;int num=0;
while(tmp<=x) tmp*=k,num++;
num--;tmp/=k;
while(x)
{
while(x>=tmp) x-=tmp,cnt[num]++;
tmp/=k;num--;
}
}
for(int i=0;i<=100;i++) if(cnt[i]>1) {printf("NO\n");return;}
printf("YES\n");
}
int main()
{
int t;scanf("%d",&t);
while(t--) rua();
return 0;
}
D. Count the Arrays
题意:n个数的范围是[1,m],能构造出多少个序列只有一对相同的,且存在一个位置i,i前递增,i后递减;
分析:m中选n-1个数,最大的放中间,剩下的放在左右,再多一个重复的,但不能等于最大;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
const int mod=998244353;
const ll INF=1e18;
int n,m;
ll fac[maxn];
ll qpow(ll x,int n)
{
ll res=1;
while(n)
{
if(n&1) res=(res*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return res;
}
ll inv(ll x){return qpow(x,mod-2);}
int main()
{
fac[0]=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=m+1;i++) fac[i]=fac[i-1]*i%mod;
if(n==2) puts("0");
else printf("%lld\n",(1ll*n-2)*fac[m]%mod*inv(fac[n-1])%mod*inv(fac[m-n+1])%mod*qpow(2ll,n-3)%mod);
}
E. Array Shrinking
题意:两个相同的x可以变成一个x+1,求最短长度;
分析:区间dp,每个区间先暴力check,再从子区间转移答案;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=2e5+7;
const int mod=1e9+7;
const ll INF=1e18;
int n,a[maxn],dp[1010][1010];
int solve(int l,int r)
{
stack<int> st;
for (int i=l;i<=r;++i)
{
int tmp=a[i];
while((int)st.size() && st.top()==tmp)
{
st.pop();
++tmp;
}
st.push(tmp);
}
return (int)st.size();
}
void rua()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int len=1;len<=n;++len)
for(int l=1;l+len-1<=n;++l)
{
int r=l+len-1;
dp[l][r]=solve(l,r);
for(int k=l;k<r;++k)
dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
}
printf("%d\n",dp[1][n]);
}
int main()
{
rua();
return 0;
}