Educational Codeforces Round 88

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} 2i1ih+(i1)c,始终大于等于偶数的情况且成单调下降。可以用二分查找奇数情况时最接近的答案
我的处理是把表达式计算出来 i ∗ h + ( i − 1 ) ∗ c 2 ∗ i − 1 − t \dfrac{i*h+(i-1)*c}{2*i-1}-t 2i1ih+(i1)ct,令其等于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,rsum(l,r)max(a[l],a[r])
注意到 − 30 ≤ a i ≤ 30 -30\le a_i\le30 30ai30范围很小,因此枚举最大值求满足情况的最大连续子序列

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 p1pk表示下标的全排列
结论 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}} (k1dn1),枚举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;
	}
}

你可能感兴趣的:(cf)