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<int> 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+c2\dfrac{h+c}{2},奇數操作溫度爲ih+(i1)c2i1\dfrac{i*h+(i-1)*c}{2*i-1},始終大於等於偶數的情況且成單調下降。可以用二分查找奇數情況時最接近的答案
我的處理是把表達式計算出來ih+(i1)c2i1t\dfrac{i*h+(i-1)*c}{2*i-1}-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<double, int> >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,rsum(l,r)max(a[l],a[r])\displaystyle \sum\limits_{l,r}sum(l,r)-max(a[l],a[r])
注意到30ai30-30\le a_i\le30範圍很小,因此枚舉最大值求滿足情況的最大連續子序列

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

求滿足((xmoda1)moda2)modak=((xmodap1)modap2)modapk\displaystyle ((x\bmod a_1)\bmod a_2)\dots\bmod a_k=((x\bmod a_{p1})\bmod a_{p2})\dots\bmod a_{p_k},其中p1pkp_1\dots p_k表示下標的全排列
結論d,k1d,k2d,kkdd,k_1d,k_2d\dots,k_kd,其中表示形成以d的倍數爲序列時滿足情況都爲d爲餘數
在套用組合公式(nd1k1)\displaystyle {\frac{n}{d}-1\choose {k-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;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章