码迷,mamicode.com
首页 > 其他好文 > 详细

AtCoder Beginner Contest 172 题解

时间:2020-06-27 22:51:37      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:href   for   mat   sum   传说   ++   air   方法   size   

AtCoder Beginner Contest 172 题解

A - Calc

程序如下(真的有人需要嘛):

#include<bits/stdc++.h>
using namespace std;

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int a;
    cin>>a;
    cout<<a+a*a+a*a*a<<endl;

    return 0;
}

B - Minor Change

程序如下(应该没人需要吧):

#include<bits/stdc++.h>
using namespace std;

string s,t;

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin>>s>>t;
    int ans=0;
    for(int i=0;i<s.size();i++)ans+=s[i]!=t[i];
    cout<<ans<<endl;

    return 0;
}

C - Tsundoku

感性地理解,你在A桌上看的书越多,你在B桌上看的书越少。也就是说,你在A桌上每多看一本书,你在B桌上就要放下一些书。

维护A、B桌看的书的本数。从小到大枚举A桌看的书的本数,B桌看的书的本数就会递减。这个就是传说中的two pointers,然后程序就好写了。

程序如下:

#include<bits/stdc++.h>
using namespace std;

int n,m,k;
int a[200005],b[200005];

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    long long tot=0;
    for(int i=1;i<=m;i++){
        cin>>b[i];
        tot+=b[i];
    }
    int ans=0;
    for(int ia=0,ib=m;ia<=n;ia++){
        tot+=a[ia];
        while(tot>k&&ib>0)tot-=b[ib--];
        if(tot>k)break;
        ans=max(ans,ia+ib);
    }
    cout<<ans<<endl;

    return 0;
}

D - Sum of Divisors

正着想,从\(1\)\(N\)枚举,求出一个数的质因数个数然后乘以它本身未尝不可,但是反着来有更简单的实现方法。

对于一个数,它是它倍数的因数,所以我们从\(1\)\(N\)枚举一个数,加上它的所有倍数的和就可以算出答案了。

程序如下:

#include<bits/stdc++.h>
using namespace std;

long long ans;
int n;

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j+=i){
            ans+=j;
        }
    }
    cout<<ans<<endl;

    return 0;
}

E - NEQ

(根据咱的习惯把题目里的\(M\)\(N\)都写成了小写的说)

首先不考虑\(B\),只考虑\(A\)。容易看出所有可能的\(A\)\(m^\underline n\)种。

然后对于每一种\(A\),我们考虑有多少种不合法的\(B\)的情况。

假设有\(k\)个不合法的位置,那么其余合法的位置有\(n-k\)个,可以放的数字有\(m-k\)个,那么其余合法的位置就有\((m-k)^\underline{n-k}\)种可能的摆放方法。然后根据容斥原理可以得到如下公式,表示对于每一种\(A\)有多少个合法的\(B\)

\[\sum_{k=0}^n\binom n k(-1)^k(m-k)^\underline{n-k} \]

结合之前对于\(A\)的可能种数的计算,本题答案如下:

\[m^\underline n\sum_{k=0}^n\binom n k(-1)^k(m-k)^\underline{n-k} \]

写成对于程序实现友好的形式:

\[m^\underline n\sum_{k=0}^n\binom n k(-1)^k(m-k)^\underline{n-k} \]

程序如下(但是不比上面的公式好懂):

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mod=1e9+7;

inline ll qpow(ll a,ll n){
    ll res=1;
    while(n){
        if(n&1)res=res*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return res;
}

int n,m;
ll ans,f[500005]={1},inv[500005]={1};

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    for(int i=1;i<=5e5;i++){
        f[i]=f[i-1]*i%mod;
        inv[i]=qpow(f[i],mod-2);
    }
    cin>>n>>m;
    for(int i=0;i<=n;i++){
        ans=(ans+f[n]*inv[i]%mod*inv[n-i]%mod*((i&1)?-1:1)*f[m-i]%mod*inv[m-n]%mod)%mod;
    }
    for(int i=m-n+1;i<=m;i++)ans=ans*i%mod;
    cout<<(ans+mod)%mod<<endl;

    return 0;
}

F - Unfair Nim

咕咕咕咕咕咕咕咕咕咕咕

AtCoder Beginner Contest 172 题解

标签:href   for   mat   sum   传说   ++   air   方法   size   

原文地址:https://www.cnblogs.com/BlahDuckling747/p/13200280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!