AtCoder Beginner Contest 172 题解

Posted blahduckling747

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 172 题解相关的知识,希望对你有一定的参考价值。

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}^ninom n k(-1)^k(m-k)^underline{n-k} ]

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

[m^underline nsum_{k=0}^ninom n k(-1)^k(m-k)^underline{n-k} ]

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

[m^underline nsum_{k=0}^ninom 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 题解的主要内容,如果未能解决你的问题,请参考以下文章