Codeforces Round 928 (Div. 4)

B题:

看每行是否有单独的一个 \(1\)。如果有的话就肯定是三角形,否则就是正方形。

主要需要注意的是这里要用 \(\rm vector<string>\) 而不能用二维的 \(\rm int\) 数组,否则在第一个输入

000
011
011

一个个输出的话是

0 11 11 
0 0 0 
0 0 0 

也就是说在输入第二行 \(011\) 结束的时候换行才把 \(11\) 读入数组中,显然不对。
(其实题目已经规定了输入的得是字符没看到qwq)

#include <bits/stdc++.h>

void solve() {
	int n;
	std::cin >> n;
	std::vector<std::string> s(n);
	for (int i = 0; i < n; i++) std::cin >> s[i];
	for (int i = 0; i < n; i++) {
		if (std::count(s[i].begin(), s[i].end(), '1') == 1) {
			std::cout << "TRIANGLE\n";
			return;
		}
	}
	std::cout << "SQUARE\n";
}

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

C题:

如果直接暴力做的话是会超时的:

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

int f(int x) {
	int ans = 0;
	while (x) {
		ans += x % 10;
		x /= 10;
	}
	return ans;
}

void solve() {
	int n;
	cin >> n;
	i64 sum = 0;
	for (int i = 1; i <= n; i++) sum += f(i);
	cout << sum << "\n";
}
int main()
{
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int t;
	cin >> t;
	while (t--) solve();
	return 0;
}

可以观察发现性质,一个数 \(n\) 要输出的结果可以通过前一个数 \(n-1\) 的结果加上这个数本身的各位之和得出,由此考虑先预处理出结果(递推)再一起输出。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

const int N = 2e5 + 5;
i64 f[N];

void solve() {
	int n;
	cin >> n;
	cout << f[n] << "\n";
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int t;
	cin >> t;
	for (int i = 1; i <= N; i++) {
		f[i] = f[i - 1];
		int x = i;
		while (x) f[i] += x % 10, x /= 10;
	}
	while (t--) solve();
	return 0;
}

D题:

本题可以利用异或的性质。与一个数 \(n\) 相匹配的是 \(2^{31}-1\) 异或上 \(n\) 的值。我们可以用 \(\rm multiset\) 来维护满足这个性质的数,如果有就将这个数从集合中弹出,并让计数器 +1, 反之则把这个数加入集合。最后输出计数器的个数。

C++ 20 写法:

#include <bits/stdc++.h>

using i64 = long long;

void solve() {
    int n;
    std::cin >> n;
    
    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    
    std::multiset<int> s;
    int ans = n;
    for (int i = 0; i < n; i++) {
        if (s.contains(a[i] ^ ((1 << 31) - 1))) {
            s.extract(a[i] ^ ((1 << 31) - 1));
            ans--;
        } else {
            s.insert(a[i]);
        }
    }
    std::cout << ans << "\n";
}

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

另一种等价的写法:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 200005;

int a[N];
int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        multiset<int> se;
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            if (se.find(a[i] ^ INT_MAX) != se.end()) {
                se.erase(se.find(a[i] ^ INT_MAX));
            } else {
                se.insert(a[i]);
                ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

E题:

思路:第一轮是 \(1\) \(3\) \(5\) \(7\)......
第二轮是 \(2\) \(6\) \(10\).......
...
\(1 \sim n\) 中的奇数个数为 \(\dfrac{n+1}{2}\)。看每轮中 \(k\) 是否满足在这个范围内,是的话直接输出 \(2k-1\)\(2\) 的轮数次幂,否则一直找下去

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

void solve() {
	int n, k;
	cin >> n >> k;
	int cnt = 0;
	while (k > (n + 1) / 2) {
		int x = (n + 1) / 2;
		n -= x;
		k -= x;
		cnt++;
	}
	cout << (2 * k - 1) * (1 << cnt) << "\n";
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int t;
	cin >> t;
	while (t--) solve();
	return 0;
}
posted @ 2024-05-07 23:36  胖柚の工作室  阅读(19)  评论(0)    收藏  举报