AtCoder Beginner Contest 110题解
文章目录
- AtCoder Beginner Contest 110题解
-
- A - Maximize the Formula
-
- 题目大意
- 思路
- 代码
- B - 1 Dimensional World's Tale
-
- 题目大意
- 思路
- 代码
- C - String Transformation
-
- 题目大意
- 思路
- 代码
- D - Factorization
-
- 题目大意
- 思路
- 代码
A - Maximize the Formula
◇题目传送门◆
题目大意
给定三个数字A,B,CA,B,CA,B,C,要求使用这三个数字组成一个两位数及一个一位数,使得他们的和最大
思路
似乎没有什么可以讲的,直接给出代码吧。
代码
#include<cstdio> #include<algorithm> using namespace std;int main() {
#ifdef LOACLfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifint a[3];scanf("%d %d %d",&a[0],&a[1],&a[2]);sort(a,a+3);printf("%d\n",a[2]*10+a[1]+a[0]);return 0; }
B - 1 Dimensional World’s Tale
◇题目传送门◆
题目大意
给定两个数N,MN,MN,M和数轴上的两个点X,YX,YX,Y与NNN个点x1,x2,x3,…,xNx_1,x_2,x_3,\ldots,x_Nx1?,x2?,x3?,…,xN?和MMM个点y1,y2,y3,…,yMy_1,y_2,y_3,\ldots,y_My1?,y2?,y3?,…,yM?,要求找出一个点ZZZ,使得它满足以下条件:
- X<Z≤YX<Z\le YX<Z≤Y
- x1,x2,x3,…,xN<Zx_1,x_2,x_3,\ldots,x_N<Zx1?,x2?,x3?,…,xN?<Z
- y1,y2,y3,…,yM≥Zy_1,y_2,y_3,\ldots,y_M\ge Zy1?,y2?,y3?,…,yM?≥Z
思路
我们记x0=X,y0=Yx_0=X,y_0=Yx0?=X,y0?=Y,仔细分析题目可以发现,当存在max?{x0,x1,x2,…,xN}<min?{y0,y1,y2…,yM}\max\{x_0,x_1,x_2,\ldots,x_N\}<\min\{y_0,y_1,y_2\ldots,y_M\}max{ x0?,x1?,x2?,…,xN?}<min{ y0?,y1?,y2?…,yM?}时,就会有ZZZ存在。
所以直接给出代码:
代码
#include<cstdio> #include<algorithm> using namespace std;const int Maxn=100; int N,M,X,Y; int A[Maxn+5],B[Maxn+5];int main() {
#ifdef LOACLfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifscanf("%d %d %d %d",&N,&M,&A[0],&B[0]);for(int i=1;i<=N;i++)scanf("%d",&A[i]);for(int i=1;i<=M;i++)scanf("%d",&B[i]);int maxa=*max_element(A,A+N+1);int minb=*min_element(B,B+M+1);if(maxa<minb)puts("No War");else puts("War");return 0; }
C - String Transformation
◇题目传送门◆
题目大意
给定两个串S,TS,TS,T,保证两串长度相等。要求使用如下操作,使得S,TS,TS,T相同:
操作:从26个字母中选择两个字母c1,c2c_1,c_2c1?,c2?,在SSS中,将所有的c1c_1c1?替换为c2c_2c2?,所有的c2c_2c2?替换为c1c_1c1?。
思路
不难发现在串SSS中,每个字母和串TTT中的每个字母是有一一对应的关系。所以我们考虑在串SSS中是否满足这个对应关系,在串TTT中是否满足对应关系。想到这个即可过掉此题。
代码
#include<set> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;const int Maxn=2*1e5;char s[Maxn+5],t[Maxn+5]; int c[256+5];int main() {
#ifdef LOACLfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifscanf("%s %s",s,t);int len=strlen(s);memset(c,-1,sizeof c);set<char> cnt;for(int i=0;i<len;i++)cnt.insert(s[i]);for(int i=0;i<len;i++) {
if(c[t[i]]!=-1&&c[t[i]]!=s[i]) {
if(t[i]==s[i]&&cnt.size()<26)continue;puts("No");return 0;}c[t[i]]=s[i];}memset(c,-1,sizeof c);for(int i=0;i<len;i++) {
if(c[s[i]]!=-1&&c[s[i]]!=t[i]) {
if(t[i]==s[i]&&cnt.size()<26)continue;puts("No");return 0;}c[s[i]]=t[i];}puts("Yes");return 0; }
D - Factorization
◇题目传送门◆
题目大意
给定两个数N,MN,MN,M,要求找出NNN个数,使得这NNN个数的乘积等于MMM。输出方案数模109+710^9+7109+7。
思路
仔细分析可发现,这NNN个数要么是111,要么就是NNN的质因数的乘积。
很自然的就扯到了唯一分解和组合数学上去。
记M=p1a1p2a2?pmamM=p_1^{a_1}p_2^{a_2}\cdots p_m^{a_m}M=p1a1??p2a2???pmam??,其中p1,p2,…,pmp_1,p_2,\ldots,p_mp1?,p2?,…,pm?为质数。
当我们将aia_iai?个质数pip_ipi?(其中1≤i≤m1\le i\le m1≤i≤m)加入到NNN个数中,就相当于将N+ai?1N+a_i-1N+ai??1个数分成N?1N-1N?1块的组合数。
所以我们就可以得到:此时的方案数为C(N+ai?1,N?1)C(N+a_i-1,N-1)C(N+ai??1,N?1)。而由于在两个方案之间,有一个数不同即被视为不同,所以,我们只需要将所有的方案数乘上即可。
即方案数为∏i=1mC(N+ai?1,N?1)\prod_{i=1}^{m}C(N+a_i-1,N-1)i=1∏m?C(N+ai??1,N?1)
注意此时若M≠1M\ne1M??=1时,答案是还需乘上NNN的。(请读者自己思考)
特别注意:由于这道题要求取模,而组合数计算需要除法,所以我们必须使用逆元!不知道逆元的读者请点这里
接下来分析时间复杂度:
预处理阶乘和逆元需要O(Nlog?2Mod)O(N\log_2Mod)O(Nlog2?Mod)。
唯一分解所需要的时间为O(M)O(\sqrt{M})O(M?)。
计算答案需要O(1)O(1)O(1)。
又由于NNN远小于MMM,所以,总时间复杂度为O(M)O(\sqrt{M})O(M?)。
代码
#include<cmath> #include<cstdio> #include<algorithm> using namespace std;typedef long long ll; const int Mod=1e9+7; const int Maxn=1.5*1e5;int N,M;ll PowMod(ll a,int b) {
ll ret=1;while(b) {
if(b&1)ret=ret*a%Mod;a=a*a%Mod;b>>=1;}return ret; }ll f[Maxn+5]; ll inv[Maxn+5];void Prepare() {
f[0]=1;for(int i=1;i<=Maxn;i++)f[i]=f[i-1]*i%Mod;inv[0]=1;inv[Maxn]=PowMod(f[Maxn],Mod-2);for(int i=Maxn-1;i>0;i--)inv[i]=inv[i+1]*(i+1)%Mod; }ll F(int a,int b) {
return f[a+b-1]*inv[a-1]%Mod*inv[b]%Mod; }//C(a+b-1,a-1)int main() {
#ifdef LOACLfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifscanf("%d %d",&N,&M);Prepare();int lim=sqrt(M);ll ans=1;for(int i=2;i<=lim;i++)if(M%i==0) {
int cnt=0;while(M%i==0)M/=i,cnt++;ans=ans*F(N,cnt)%Mod;}if(M!=1)ans=ans*N%Mod;printf("%lld",ans);return 0; }
最后给出我的排名: