A. T-shirt

前 $A$ 名一定获得衣服,在 $[A+1, B]$ 之间的人将随机挑 $C$ 个人获得衣服。

若已知他排名于 $X$,求其获得衣服的概率。

分析

int main() {
	int A, B, C, X;
	cin >> A >> B >> C >> X;
	double ans = 0;
	if (X <= A) {
		ans = 1;
	} else if (X <= B && A != B) {
		ans = 1.0 * C / (B - A);
	}
	printf("%.12lf", ans);
	return 0;
}

全部代码请看:Atcoder/ABC242/ABC242A.cpp

B. Minimize Ordering

给定一个字符串 $S$,请找到 $S$ 的重排 $S’$,并且使其字典序尽可能小。

分析

int main() {
	string s;
	cin >> s;
	std::sort(s.begin(), s.end());
	cout << s;
	return 0;
}

全部代码请看:Atcoder/ABC242/ABC242B.cpp

C. 1111gal password

相邻数字差为 $1$ 且有 $N$ 位的数字有多少个。

分析

const int P = 998244353;

int main() {
	int n;
	cin >> n;
	vector<int> v1(10, 1), v2(10);
	for (int i = 1; i < n; i++) {
		for (int j = 1; j < 9; j++) {
			v2[j] = ((v1[j - 1] + v1[j]) % P + v1[j + 1]) % P;
		}
		v2[0] = v1[1], v2[9] = v1[8];
		v1 = v2;
	}
	int sum = 0;
	for (int i = 0; i < 9; i++) {
		sum = (sum + v1[i]) % P;
	}
	cout << sum;
	return 0;
}

全部代码请看:Atcoder/ABC242/ABC242C.cpp

D. ABC Transform

给定包含 ABC 的字符串 $S$,可以对字符串做如下变换:

  • A->BCB->CAC->AB

多次询问,回答经过 $t_i$ 次变换后第 $k_i$ 个字符。

分析

注意到一个字符经过变换后会变成两个字符,是类似二叉树的东西。

因此我们可以沿着树向上走,而且每向上走一层,长度就少一半,故很快就到 $0$。

似乎有更快的位运算做法,有空再回来看看吧。

int main() {
	string s;
	int Q;
	cin >> s >> Q;
	std::function<ll(ll, ll)> get = [&](ll pos, ll t) -> ll {
		if (t == 0) {
			return s[pos] - 'A';
		} else if (pos == 0) {
			return (s[0] - 'A' + t) % 3;
		} else if (pos % 2 == 0) {
			return get(pos / 2, t - 1) + 1;
		} else {
			return get(pos / 2, t - 1) + 2;
		}
	};
	while (Q--) {
		ll ti, ki;
		cin >> ti >> ki;
		cout << char(get(ki - 1, ti) % 3 + 'A') << "\n";
	}
	return 0;
}

全部代码请看:Atcoder/ABC242/ABC242D.cpp

E. (∀x∀)

给定一个长为 $N$ 的字符串 $S$,计算满足下列条件的字符串数量:

  • $X$ 是一个长为 $N$ 的回文串。
  • 在字典序下有 $X \leqslant S$。

分析

类似于数位 DP,考虑第 $i$ 位如果满足 $X_i < S_i$,那么中间几位可以随便放。

最后,如果存在的话,注意特判中间一位,和其他特殊情况。

const int N = 1E6, P = 998244353;

int main() {
	vector<int> pw(N);
	pw[0] = 1;
	for (int i = 1; i < N; i++) {
		pw[i] = 1ll * pw[i - 1] * 26 % P;
	}
	int T;
	cin >> T;
	while (T--) {
		int n;
		string s;
		cin >> n >> s;
		ll sum = 0;
		int mid = n / 2;
		for (int i = 0; i < mid; i++) {
			sum += 1ll * pw[n - mid - i - 1] * (s[i] - 'A') % P;
		}
		if (n % 2 == 1) {
			sum += s[mid] - 'A';
		}
		string s2(s.begin() + (n - mid), s.end());
		string s3(s.begin(), s.begin() + mid);
		std::reverse(s3.begin(), s3.end());
		if (s3 <= s2)
			sum++;
		cout << sum % P << "\n";
	}
	return 0;
}

全部代码请看:Atcoder/ABC242/ABC242E.cpp