2019四月月赛

先发一下思路,可能一会儿会放AC代码

A 切火腿肠

考点:gcd
我们假设每根火腿肠的长度为L,然后把它们拼接成长长的一条,然后切成m块
那么它所需要切的刀数即==m(若恰好切完,包括最右端,若有剩余,不包括最右端)
但是考虑到有些地方已经有了天然的分界点(需要切的地方与本身自己因拼接而存在的断点重合)
这个天然分界点的个数为gcd(n,m)(因为已有断点,不用再切,需要被减去)
所以ans = m - gcd(n,m);

B 翻硬币

考点:或许是观察(样例)找规律吧orz
但是!!!这道题,需要,开long long!!!
orz orz orz
orz,于是无数的人光荣倒在了WA 20下 (虽然我自己WA是因为暴力)
我们观察一下样例,发现"BBW" - > "WBB";"BWBWBW" -> "WWWBBB"
最终,所有的B都移到了右边,所有的W都移到了左边;
也就是每一个W都会和它左边的每个B交换一次,所以直接求它需要换的次数即可

C 三分数组

考点:前缀和
首先我们

E 越狱

考点:排列组合 + 简单容斥
我们只需要求出所有分配的方案再减去所有“不合法”的方案即可,需要注意的是这道题需要用到快速幂
共有M种总教,N个房间
所以总方案 = \(M^n\)


代码如下

A

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

int n, m;

int gcd(int a, int b){
    return b ? gcd(b, a % b) : a;
}

int main(){
    scanf("%d%d", &n, &m);
    printf("%d",m - gcd(n, m));
        return 0;
}

B

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
long long n, b, ans;
string s;
int main(){
    cin>>s;
    n = s.length();
    for(int i = 0; i < n; i ++)
        if(s[i] == 'B')b ++;
        else ans += b;
    cout<<ans;
        return 0;
}

C

E

#include <stdio.h> 
#include <bits/stdc++.h> 
#define ll long long

const int mod = 100003;

using namespace std;

ll n, m, qwq, qaq, ans;

ll montgomery(ll a, ll n){
    ll ans = 1;
    while(n){
        if(n & 1)ans = (ans * a) % mod;
        n = n >> 1;
        a = (a * a) % mod;
    }
    return ans;
}

int main(){
    scanf("%lld%lld",&m,&n);
    ans = (montgomery(m,n) + mod-(m * montgomery(m - 1,n - 1)) % mod)%mod;
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qwqq/p/10742033.html