先发一下思路,可能一会儿会放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);
不合法的方案 = (M^n−M∗(M−1)^{n-1})
代码如下
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;
}
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
", ans);
return 0;
}