A - A Healthy Breakfast
枚举一下,只要R在M之前就行了
#include <iostream>
using namespace std;
int main()
{
char a,b,c;
cin >> a >> b >> c;
if((a == 'R' && (b == 'M' || c == 'M')) || (b == 'R' && c == 'M'))
{
cout << "Yes" << endl;
}
else cout << "No" << endl;
return 0;
}
B - Vertical Reading
题意:把字符串每隔w个字符拆分一次,取每段的第c个字符拼接在一起,看能不能得到t
数据范围很小,直接暴力枚举(*^_^*)
#include <iostream>
using namespace std;
int main()
{
string a, b;
cin >> a >> b;
a = ' ' +a;
int na = a.size()-1;
//枚举每一种长度
for(int w = 1; w < na; w++)
{
//枚举c
for(int c = 1; c <= w; c++)
{
string ans = "";
for(int i = 1; i <= na; i += w)
{
//判断第c个字符是否超过字符串长度
if(i + c - 1 <= na) ans += a[i + c - 1];
}
if(ans == b)
{
puts("Yes");
return 0;
}
}
}
puts("No");
return 0;
}
C - Move It
分析:因为最终每个箱子中只有一个小球,并且要使移动的代价最小,所以只需要把每个箱子里除去最大权值的物品逐个加起来即可,代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int N = 1e5+10;
int w[N];
bool cmp(int i, int j)
{
return w[i] < w[j];
}
int main()
{
int n;
cin >> n;
map<int, vector<int>> mp;
int x;
for(int i = 1; i <= n; i++)
{
cin >> x;
mp[x].push_back(i);
}
for(int i = 1; i <= n; i++) cin >> w[i];
long long ans = 0;
for(auto t : mp)
{
vector<int> v = t.second;
if(v.size() <= 1) continue;
sort(v.begin(), v.end(), cmp);
//把除了最大的数加起来
for(int i = 0; i < v.size() - 1; i++)
{
ans += w[v[i]];
}
}
cout << ans << endl;
return 0;
}
D - Ghost Ants
分析:因为所有蚂蚁的速度都是相同的,所以方向相同的蚂蚁是不会碰头的,这样就可以把蚂蚁分成两个部分,一部分朝向正方向,一部分朝向负方向,然后我们就可以枚举正方向的每个蚂蚁都能与负方向的哪些蚂蚁碰头,为了降低时间复杂度,这个过程我们可以先将负方向的蚂蚁位置进行从小到大排序,然后利用二分来去寻找合适能碰头的蚂蚁的数量,代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int n;
long long t;
cin >> n >> t;
string s;
cin >> s;
s = ' ' + s;
vector<long long> a;
vector<long long> b;
long long x;
for(int i = 1; i <= n; i++)
{
cin >> x;
if(s[i] == '1') a.push_back(x);
else b.push_back(x);
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
long long ans = 0;
for(long long y : a)
{
auto l = lower_bound(b.begin(), b.end(), y), r = upper_bound(b.begin(), b.end(), y + t + t);
ans += r - l;
}
cout << ans << endl;
return 0;
}
E - Random Swaps of Balls
分析:首先对于位置1,黑球有两种选择,一是改变位置,二是保持在原地,然后我们可以计算一次操作黑球的期望位置:
对于保持在原地,我们可以两个都不选择位置1处的球,它的概率是,也可以选择两个都是位置1处的球,它的概率为,因此,保持原地的概率为,此时保持原地的期望为
对于改变位置,我们有的概率选择位置1,有的概率选择其他位置,并且两者可以互换位置,所以要乘以2,那么期望位置为:,
将两者相加后即是一次操作后的期望位置。
算出这次的期望位置后,我们通过此次的期望位置来算出后面的期望位置,只是需要把保持在原地乘以1换成乘以此次的期望值,把改变位置的期望值中减1,改成减去此次的期望值,假如此次的期望为f[i],则
然后循环k次就可以了,
对于第0次,它的期望就是1,代码如下:
#include <iostream>
using namespace std;
using ll = long long;
const int mod = 998244353, N = 1e5+10;
ll f[N];
ll qmi(ll a, ll b)
{
ll res = 1;
a%=mod;
while(b)
{
if(b&1) res = 1LL * res * a % mod;
a = 1LL * a * a % mod;
b >>= 1;
}
return res;
}
ll inv(ll x)
{
return qmi(x, mod-2);
}
int main()
{
ll n, k;
cin >> n >> k;
f[0] = 1;
//求n*n逆元
ll invn = inv(n*n);
ll sum = ((n-1) * (n-1) % mod + 1) % mod;
ll p = (n + 1)*n / 2 % mod;
for(int i = 1; i <= k; i++)
{
f[i] = f[i-1]*sum % mod * invn % mod;
f[i] += 2LL * invn % mod * (p - f[i-1]) % mod;
f[i] = (f[i] % mod + mod)%mod;
}
cout << f[k] << endl;
return 0;
}
F、E不会,以后再补