ABC 367 题解

云岚天上飘 / 2024-08-18 / 原文

AtCoder Beginner Contest 367 题解:

\(Problem \hspace{2mm} A - Shout \hspace{2mm} Everyday\)

题目链接

opinion:

小模拟,循环 \(B\)\(C\),检验是否出现 \(A\)

code:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
ll a, b, c;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> a >> b >> c;
	int now = b;
	while (true) {
		if (now == a) {
			cout << "No";
			return 0;
		}
		if (now == c) break;
		now += 1;
		now %= 24;
	}
	cout << "Yes";
	return 0;
}

\(\newline\)
\(\newline\)

\(Problem \hspace{2mm} B - Cut .0\)

题目链接

opinion:

读入一个字符串,将末尾连续的 \(0\) 删除。

一个值得注意的点是如果小数全被删除,小数点不应保留。

code:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	string s; cin >> s;
	bool fg = false;
	int n = s.size();
	while (s[n - 1] == '0') n --;
	if (s[n - 1] == '.') n -= 1;
	for (int i = 0; i < n; ++i)
		cout << s[i];
	return 0;
}

\(\newline\)
\(\newline\)

\(Problem \hspace{2mm} C - Enumerate \hspace{2mm} Sequences\)

题目链接

opinion:

基础 \(dfs\) 题目。

由于我们从 \(1\) 开始枚举,保证了字典序。

code:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 1e6 + 10;
int n, k, a[N], x[N];
inline void dfs(int step, int ret) {
	if (step > n) {
		// 选完了 n 个数,可以退出了。
		if (ret % k == 0) {
			// 满足条件就输出答案。
			for (int i = 1; i <= n; ++i)
				cout << x[i] << " ";
			cout << "\n";
		}
		return ;
	}
	for (int i = 1; i <= a[step]; ++i) {
		//枚举范围。
		x[step] = i;
		//选了这个数之后,加和,选下一个数。
		dfs(step + 1, ret + i);
		x[step] = 0;
	}
	//ret储存的是已选数的和,以免再次循环计算。
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> k;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	dfs(1, 0);
	return 0;
}

~~
\(\newline\)
\(\newline\)

\(Problem \hspace{2mm} D - Pedometer\)

题目链接

opinion:

code:

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 1e6 + 10;
ll n, m, a[N], cnt[N], pre[N];
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        a[n + i] = a[i];
    }
    for (int i = 2; i <= n + n - 1; i++) {
        pre[i] = pre[i - 1] + a[i - 1];
        pre[i] %= m;
    }
    for (int i = 1; i <= n; i++)
        cnt[pre[i]]++;
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += cnt[pre[i]] - 1;
        cnt[pre[i + n]]++;
        cnt[pre[i]]--;
    }
    cout << ans;
    return 0;
}

\(\newline\)
\(\newline\)

\(Problem \hspace{2mm} F - Rearrange \hspace{2mm} Query\)

题目链接

opinion:

Hash + 前缀和,竟然没被卡掉,绷不住了。

code:

#include <bits/stdc++.h>
#include <random>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 1e6 + 10;
const ll mod = 1e9 + 7;
ll n, q, a[N], b[N];
ll Hash[N];
ll pre_a[N], pre_b[N];
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
    cin >> n >> q;
    for (int i = 1; i <= n; ++i)
    	cin >> a[i];
    for (int i = 1; i <= n; ++i)
    	cin >> b[i];
    srand(time(NULL));
    for (int i = 1; i <= n; ++i)
    	Hash[i] = rand() % mod;
    for (int i = 1; i <= n; ++i) {
    	(pre_a[i] = pre_a[i - 1] + Hash[a[i]]) %= mod;
    	(pre_b[i] = pre_b[i - 1] + Hash[b[i]]) %= mod;
    }
    while (q -- ) {
    	int l[2], r[2];
    	cin >> l[0] >> r[0] >> l[1] >> r[1];
    	ll ans1 = pre_a[r[0]] - pre_a[l[0] - 1] + mod;
    	ll ans2 = pre_b[r[1]] - pre_b[l[1] - 1] + mod;
		//前缀和
    	if (ans1 % mod == ans2 % mod) puts("Yes");
    	else puts("No");
	}
    return 0;
}

\(\newline\)
\(\newline\)