A.Berland Poker
给你n张牌,其中m张joker,平均分给k个人,保证n%k==0
问分数的最大值。这里分数指拿到joker最多的人的牌的数量-拿到joker最少的人的牌的数量。那么我们可以知道,让其中一个人尽可能全部拿joker,剩下的尽可能平分即可。
int n, m, k;
void solve()
{
cin >> n >> m >> k;
int maxn = n / k;
if (maxn <= m)
cout << maxn - (int)ceil((1.0 * m - maxn) / (1.0 * k - 1)) << endl;
else
cout << m << endl;
}
B.New Theatre Square
给出一个只包含’ . ‘和’ * ‘的 n × m n×m n×m的矩阵,和消除一个’.‘的耗费x,消除同一行的连续两个’.'的耗费y。求最小耗费
int n, m, k;
int x, y;
char mp[105][1005];
void solve()
{
cin >> n >> m >> x >> y;
itn ans = 0;
for (int i = 1; i <= n; i++)
cin >> mp[i];
if (x * 2 > y)
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < m;)
{
if (mp[i][j] == '.')
{
if (j == m - 1)ans += x, j++;
else if (mp[i][j + 1] == '.')
{
ans += y;
j += 2;
}
else
{
ans += x;
j += 2;//说明下一个肯定是'*',直接可以跳过
}
}
else j++;
}
}
}
else
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < m; j++)
{
if (mp[i][j] == '.')
{
ans += x;
}
}
}
}
cout << ans << endl;
}
C.Mixing Water
给你热水和冷水,温度分别为
h
h
h,
c
c
c。
以 一杯热水->一杯冷水->一杯热水->一杯冷水->…的顺序加入一个容器内,
问最少加多少杯,可以最接近温度t。
第一个情况,
h
=
=
t
h==t
h==t,所以答案为1
第二个情况,
h
+
c
>
=
t
∗
2
h + c >= t * 2
h+c>=t∗2 ,这里注意,有一种情况是目标温度
t
<
t<
t<平均温度
(
h
+
c
)
/
2
(h+c)/2
(h+c)/2。答案为2
第三个情况,先假设加
n
+
1
n+1
n+1杯热水和n杯冷水小于等于目标温度
t
t
t。
( n + 1 ) h + n c 2 n + 1 ≤ t \frac{(n+1)h+nc}{2n+1} \leq t 2n+1(n+1)h+nc≤t ①
化简得到 n ( h + c ) + h 2 n + 1 ≤ t \frac{n(h+c)+h}{2n+1} \leq t 2n+1n(h+c)+h≤t ② n ≤ t − h 2 t − h − c n\leq\frac{t-h}{2t-h-c} n≤2t−h−ct−h ③
我们看到②式,由题可得
1
<
=
c
<
h
1 <= c < h
1<=c<h,因此
h
+
c
>
=
3
>
2
h+c >= 3 > 2
h+c>=3>2
所以根据极限的有关知识(其实是我忘了 ),我们知道式子是随着n增长递增的,可以推出,当
n
=
n
+
1
n=n+1
n=n+1,得到的温度会大于等于t。
所以
n
n
n和
n
+
1
n+1
n+1,是离
t
t
t最近的两个点,分别算他们两个温度,比较一下,就能得到答案。
long long h, c, t;
void solve()
{
cin >> h >> c >> t;
if (h == t)cout << "1\n";
else if (h + c >= t * 2)cout << "2\n";
else
{
int ans = ((t - h) / (h + c - 2 * t));
int ans1 = ans + 1;
double m1 = ((ans + 1) * h + ans * c) * 1.0 / (2 * ans + 1) * 1.0;
double m2 = ((ans1 + 1) * h + ans1 * c) * 1.0 / (2 * ans1 + 1) * 1.0;
if (fabs(m1 - t) > fabs(m2 - t))
cout << 2 * ans1 + 1 << endl;
else cout << 2 * ans + 1 << endl;
}
}
E.Modular Stability
给你n和k,要求在[1, n]中找出不同的k个数,使得
其中
1
≤
a
1
<
a
2
<
⋯
<
a
k
≤
n
1≤a1<a2<⋯<ak≤n
1≤a1<a2<⋯<ak≤n,
x
>
=
0
x>=0
x>=0
首先想到的就是,先选一个
1
1
1, 剩下的随便选,结果肯定是
0
0
0 。我们延伸出去,先选一个
2
2
2 ,发现剩下的全部选偶数,结果一定是统一的
1
1
1或
0
0
0 。显而易见,选一个基数
p
p
p,再在
[
p
+
1
,
n
]
[p+1, n]
[p+1,n] 中选
k
−
1
k-1
k−1个基数的倍数,方案数总和,即是答案。
ll n, m, k;
ll MOD = 998244353;
ll fact[1000005];
ll a[1000005];
ll pow(ll x)
{
ll n = MOD - 2;
ll res = 1;
while (n > 0)
{
if (n % 2 == 1)
res = res * x % MOD;
x = x * x % MOD;
n >>= 1;
}
return res;
}
void init() {
a[0] = a[1] = 1;
fact[0] = fact[1] = 1;
for (int i = 2; i <= 1000005; i++)
{
fact[i] = fact[i - 1] * i % MOD;
a[i] = a[i - 1] * pow(i) % MOD;
}
}
ll C(int n, int m) {
if (n < 0 || m < 0 || n < m)return 0;
return fact[n] * a[n - m] % MOD * a[m] % MOD;
}
void solve()
{
init();
cin >> n >> k;
ll ans = 0;
for (int i = 1; i <= n; i++)
ans = (ans + C(n / i - 1, k - 1)) % MOD;
cout << ans << endl;
}