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 题解的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242