The 14-th BIT Campus Programming Contest

A. 两只脑斧

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int,int>;


i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n;
	cin >> n;
	string s;
	for(int i = 1, x; i <= n; i ++) {
		cin >> s;
		x = s[0] - '0';
		if(x == 7) cout << "I";
		else if(x == 0) cout << "X";
		else if(x & 1) cout << "E";
		else cout << "I";
	}
	return 0;
}

C. 赛尔逵传说

贪心题目,因为攻击力只能是\(k\)的倍数,因此没使用一次水果相当于少挨一次打,因此我们可以贪心的选择对方攻击力最高的。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int,int>;


i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n, k, c;
	cin >> n >> k >> c;

	vector<pii> a(n);
	for(auto &[x, d] : a) cin >> d >> x;
	ranges::sort(a, greater<>());
	int res = 0;
	for(auto &[x, d] : a) {
		int y = (d + k - 1) / k - 1;
		if(y <= c) c -= y;
		else y -= c, c = 0, res += y * x;
	}
	cout << res << "\n";
	return 0;
}

E. 只有一端开口的瓶子

我们至多使用两个瓶子就一定可以排序。先要考虑的就是用一个瓶子是否可以排序,我们可以模拟一下一个瓶子的方案。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int,int>;


const int mod = 2019;

void solve() {
	int n;
	cin >> n;

	int now = 1;
	stack<int> stk;

	for(int i = 1, x; i <= n; i ++) {
		cin >> x;
		stk.push(x);
		while(not stk.empty() and stk.top() == now) 
			stk.pop(), now ++;
	}
		
	if(now == n + 1) cout << "1\n";
	else cout << "2\n";

	return;
}


i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);

	i32 T;
	cin >> T;
	while(T --) solve();

	return 0;
}

F. 风王之瞳

一个大小为\(d\times d\)正方形里面包含了\(d\)个内接正方形。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int,int>;

void solve() {
	int n, m;
	cin >> n >> m;
	int d = min(n, m);
	int res = 0;
	for(int i = 1; i <= d;i ++) 
		res += i * (n - i + 1) * (m - i + 1);
	cout << res << "\n";
	return ;
}

i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int T;
	cin >> T;
	while(T --) solve();
	return 0;
}

H. 目标是成为数论大师

求根公式解一下。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int,int>;


void solve(){
	i64 a, b;
	cin >> a >> b;
	if(a == 0) {
		cout << 1 << "\n" << b << "\n";
		return; 
	}
	i64 A = 1, B = - (2 * b + a), C = b * b;
	i64 delta = B * B - 4 * A * C;
	if(delta == 0) {
		i64 x = - B / (2 * A);
		assert(A * x * x + B * x + C == 0);
		cout << 1 << "\n" << x << "\n";
	} else {
		double d = sqrt(1.0 * delta);
		i64 x1 = - (B + d) / (2 * A);
		i64 x2 = - (B - d) / (2 * A);
		assert(x1 != x2);
		assert(A * x1 * x1 + B * x1 + C == 0);
		assert(A * x2 * x2 + B * x2 + C == 0);
		if(x1 > x2) swap(x1, x2);
		if(x1 * a < 0 or x1 - b < 0) {
			cout << 1 << "\n" << x2 << "\n";
		}else if(x2 - b < 0 or x2 * a < 0 ) {
			cout << 1 << "\n" << x1 << "\n";			
		}else{
			cout << 2 << "\n" << x1 << " " << x2 << "\n";
		}
	}
	return;
}

i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	i32 T;
	cin >> T;
	while(T --) solve();
	return 0;
}

J. 金色传说

\(p[i]\)表示长度为\(i\)的数字之和,记\(f[i]\)表示长度为\(i\)且至少存在一个符号的所有等式之和。因此对于询问\(x\),答案就是\(f[x] + p[x]\)

\(f[i]\)如何计算,我们可以考虑枚举最后一个数,然后前面的数有两种情况,没有符号和有符号。我们考虑对于最后一个数\(x\),如果存在加\(x\)就一定存在减\(x\)。因此会吧最后一个数产生的贡献全部都消掉。所以我们可以用前缀和实现快速的转移。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int,int>;

const int mod = 998244353;

struct mint {
	i64 x;

	mint(int x = 0) : x(x) {}

	mint &operator=(int o) {return x = o, *this;}

	mint &operator+=(mint o) { return (x += o.x) >= mod && (x -= mod), * this;}

	mint &operator-=(mint o) { return (x -= o.x) < 0 && (x += mod), *this;}

	mint &operator*=(mint o) { return x = x * o.x % mod, *this;}

	mint &operator^=(int b) {
		mint w = *this;
		mint ret = 1;
		for(; b; b >>= 1, w *= w) if(b & 1) ret *= w;
		return x = ret.x, *this;
	}

	friend mint operator+(mint a, mint b) { return a += b;}
	friend mint operator-(mint a, mint b) { return a -= b;}
	friend mint operator*(mint a, mint b) { return a *= b;}
	friend mint operator^(mint a, int b) { return a ^= b;}
};

i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int N = 5e5;

	vector<mint> q(N + 1);
	q[0] = 1;
	vector<mint> p(N + 1);

	for(int i = 1; i <= N; i ++) {
		q[i] = q[i - 1] * 10;
		for(int j = 0; j <= 9; j ++) 
			p[i] += p[i - 1] * 10 + j * q[i - 1];
	}

	vector<mint> preF(N + 1), preP(N + 1);
	vector<mint> f(N + 1), g(N + 1), pre(N + 1), ans(N + 1);

	for(int i = 3; i <= N; i ++) {
		preP[i] = (preP[i - 1] + p[i - 2]) * 10; 
		f[i] += preP[i] * 2;
		if(i >= 5) {
			preF[i] = (preF[i - 1] + f[i - 2]) * 10;
			f[i] += preF[i] * 2;
		}
	}

	int T;
	cin >> T;
	for(int x; T; T --) {
		cin >> x;
		if(x <= 2 ) cout << p[x].x << "\n";
		else cout << (f[x] + p[x]).x << "\n";
	}

	return 0;
}

K. 多项式求导

直接模拟求导的过程即可。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

using vi = vector<int>;
using pii = pair<int,int>;


const int mod = 998244353;


i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);

	i64 n, k;
	cin >> n >> k;
	
	vi res(n + 1);

	for(i64 i = n, x, y; i >= 0; i --) {
		cin >> y, x = i;
		for(int j = 0; j < k; j ++)
			y = y * x % mod, x = max(x - 1, 0ll);
		if(i - k >= 0) res[i - k] = y % mod; 
	}

	for(int i = n; i >= 0; i --)
		cout << res[i] << " ";
	return 0;
}

L. 旅行的意义

我们在DAG上的 dp,\(f[i]\)表示从\(i\)出发可以玩多少天。首先如果\(i\ne 1\),则需要花费\(1\)天坐火车来。第一天一定会玩,第二天有\(\frac{1}{\mathrm{e[i].size()} + 1}\)的概率会玩。

然后我们枚举所有的子节点,$f[x] \leftarrow f[x] + \frac{f[y]}{\mathrm{e[x].size()}} $。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

#define int i64

using vi = vector<int>;
using pii = pair<int, int>;

const int mod = 998244353;

int power(int x, int y) {
    int ret = 1;
    while (y) {
        if (y & 1) ret = ret * x % mod;
        x = x * x % mod;
        y /= 2;
    }
    return ret;
}

int inv(int x) {
    return power(x, mod - 2);
}

void solve() {
    int n, m;
    cin >> n >> m;

    vector<vi> e(n + 1);
    for (int x, y; m; m--) {
        cin >> x >> y;
        e[x].push_back(y);
    }

    vi f(n + 1); // f[x] 从 x 出发玩的期望天数

    auto dfs = [&](auto &&self, int x) -> int {
        if (f[x] != 0) return f[x];
        f[x] = (1 + (x != 1) + inv(e[x].size() + 1)) % mod;
        for (auto y: e[x])
            f[x] = (f[x] + inv(e[x].size()) * self(self, y)) % mod;
        return f[x];
    };

    cout << dfs(dfs, 1) << "\n";
    return;
}


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
posted @ 2024-11-24 13:45  PHarr  阅读(3)  评论(0编辑  收藏  举报