A
先尽可能多分给一个人,其他人平分
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
int n, m, k; cin >> n >> m >> k;
if (m == n) cout << 0 << endl;
else {
int pre = n / k;
//cout << "pre = " << pre << endl;
if (m <= pre) cout << m << endl;
else {
m -= pre;
//cout << "m = " << m << endl;
if (m % (k - 1) == 0) cout << pre - m / (k - 1) << endl;
else cout << pre - m / (k - 1) - 1 << endl;
}
}
}
}
B
可以花费x元把一个白块染色,y元把行相邻的两个白块染色,求最少花费把所有白块染色
处理行上连续白块的数量,判断单个染色还是两个染色省钱
char a[maxn][maxm];
vector res;
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
int n, m, x, y; cin >> n >> m >> x >> y;
res.clear();
for (int i = 0; i < n; ++i) {
int tmp = 0;
for (int j = 0; j < m; ++j) {
cin >> a[i][j];
if (a[i][j] == '*') {
if (tmp != 0) {
res.push_back(tmp);
tmp = 0;
}
}
else tmp++;
}
if (tmp != 0) res.push_back(tmp);
}
int ans = 0;
for (auto _ : res) {
if (x * 2 <= y) {
ans += _ * x;
}
else {
ans += (_ / 2) * y + (_ % 2) * x;
}
}
cout << ans << endl;
}
}
C
一杯热水一杯冷水交替倒在一个无限容积的桶里,温度为 温度和的平均,求最接近给出温度的最少操作
可以发现偶数操作始终温度为 h + c 2 \dfrac{h+c}{2} 2h+c,奇数操作温度为 i ∗ h + ( i − 1 ) ∗ c 2 ∗ i − 1 \dfrac{i*h+(i-1)*c}{2*i-1} 2∗i−1i∗h+(i−1)∗c,始终大于等于偶数的情况且成单调下降。可以用二分查找奇数情况时最接近的答案
我的处理是把表达式计算出来 i ∗ h + ( i − 1 ) ∗ c 2 ∗ i − 1 − t \dfrac{i*h+(i-1)*c}{2*i-1}-t 2∗i−1i∗h+(i−1)∗c−t,令其等于0,求出x,判断x或者x+1谁更优
int h, c, y;
double val(int x) {
return fabs(1.0 * (h + c - 2 * y) / 2 + 1.0 * (h - c) / (4 * x - 2));
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
cin >> h >> c >> y;
if (2 * y == h + c) cout << 2 << endl;
else {
vector< pair >ans;
int x1 = (y - c) / (2 * y - h - c);
if (x1 * 2 - 1 >= 0) ans.push_back(make_pair(val(x1), x1 * 2 - 1));
x1++;
if (x1 * 2 - 1 >= 0) ans.push_back(make_pair(val(x1), x1 * 2 - 1));
x1 = (h - y) / (h + c - 2 * y);
if (x1 * 2 - 1 >= 0) ans.push_back(make_pair(val(x1), x1 * 2 - 1));
x1++;
if (x1 * 2 - 1 >= 0) ans.push_back(make_pair(val(x1), x1 * 2 - 1));
ans.push_back(make_pair(fabs(1.0 * (h + c) / 2 - y), 2));
sort(ans.begin(), ans.end());
cout << ans[0].second << endl;
}
}
}
D
求最大的 ∑ l , r s u m ( l , r ) − m a x ( a [ l ] , a [ r ] ) \displaystyle \sum\limits_{l,r}sum(l,r)-max(a[l],a[r]) l,r∑sum(l,r)−max(a[l],a[r])
注意到 − 30 ≤ a i ≤ 30 -30\le a_i\le30 −30≤ai≤30范围很小,因此枚举最大值求满足情况的最大连续子序列
int a[maxn];
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
int n;
while (cin >> n) {
for (int i = 1; i <= n; ++i)
cin >> a[i];
int ans = 0;
for (int mx = 1; mx <= 30; ++mx) {
int tmp = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] > mx) tmp = 0;
else {
if (tmp < 0) tmp = 0;
tmp += a[i];
ans = max(ans, tmp - mx);
}
}
}
cout << ans << endl;
}
}
E
求满足 ( ( x m o d a 1 ) m o d a 2 ) … m o d a k = ( ( x m o d a p 1 ) m o d a p 2 ) … m o d a p k \displaystyle ((x\bmod a_1)\bmod a_2)\dots\bmod a_k=((x\bmod a_{p1})\bmod a_{p2})\dots\bmod a_{p_k} ((xmoda1)moda2)…modak=((xmodap1)modap2)…modapk,其中 p 1 … p k p_1\dots p_k p1…pk表示下标的全排列
结论 d , k 1 d , k 2 d … , k k d d,k_1d,k_2d\dots,k_kd d,k1d,k2d…,kkd,其中表示形成以d的倍数为序列时满足情况都为d为余数
在套用组合公式 ( n d − 1 k − 1 ) \displaystyle {\frac{n}{d}-1\choose {k-1}} (k−1dn−1),枚举d即可
const int mod = 998244353;
int qpow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % mod;
b >>= 1;
a = 1ll * a * a % mod;
}
return res;
}
int fib[maxn];
int main()
{
int n, k; cin >> n >> k;
if (n < k) cout << 0 << endl;
else {
fib[0] = 1;
for (int i = 1; i <= n; ++i) {
fib[i] = 1ll * fib[i - 1] * i % mod;
}
auto C = [&](int n, int m) {
if (n < 0 || m < 0 || n < m) return 0ll;
return 1ll * fib[n] * qpow(1ll * fib[m] * fib[n - m] % mod, mod - 2) % mod;
};
int ans = 0;
for (int i = 1; i <= n; ++i) {
ans = (ans + C(n / i - 1, k - 1)) % mod;
}
cout << ans << endl;
}
}