@[TOC](TheForces Round #43 (DIV2-Forces))
A题
依次类推,不难想题意就是求n中的完全平方数的个数
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
cin>>T;
while (T--) {
int n;
cin>>n;
int ans=0;
for(int i=1; i*i<=n; i++) {
ans++;
}
cout<<ans<<'\n';
}
return 0;
}
B题
想法不唯一,我的是分个数是奇数,偶数来分别讨论
偶:前面1到n跳过2,并将2放置末尾
奇:前面1到n跳过2,4,并将2,4放置末尾
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
cin>>n;
if (n<=3) {
cout<<"-1"<<'\n';
return;
}
if (n % 2 == 0) {
for(int i=1; i<=n; i++) {
if (i == 2) continue;
cout<<i<<" ";
}
cout<<"2"<<'\n';
}else {
for(int i=1; i<=n; i++) {
if (i == 2 || i == 4) continue;
cout<<i<<" ";
}
cout<<"2 4"<<'\n';
}
}
int main() {
ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
cin>>T;
while (T--) {
solve();
}
return 0;
}
C1题
需要细心考虑所有情况,很容易漏项,具体看代码中的注释部分
#include<bits/stdc++.h>
using namespace std;
void solve() {
int n, m, k;
cin >> n >> m >> k;
// 计算最大可能的彩色子数组数量
int max_m;
if (n == 1) {
max_m = 1;
} else if (n == 2) {
max_m = 3;
} else {
max_m = 3 * n - 3;//四个以上必然重复则不满足,于是考虑1,2,3的情况分别为n + (n-1) + (n-2) = 3 * n - 3
}
// 检查m是否在有效范围内
if (m < n || m > max_m) {
cout << -1 << "\n";
return;
}
// 初始化数组为全1
vector<int> a(n, 1);
int need = m - n; // 需要额外增加的数量
if (need == 0) {
// 无需额外增加,直接输出全1数组
for (int num : a) {
cout << num << " ";
}
cout << "\n";
return;
}
// 逐步修改数组元素以增加彩色子数组数量
for (int i = 1; i < n; ++i) {
if (need == 0) {
// 已满足需求,剩余元素与前一个相同
a[i] = a[i-1];
continue;
}
int max_add;
if (i == 1) {
max_add = 1; // 第二个元素最多增加1个
} else {
if (a[i-1] != a[i-2]) {
max_add = 2; // 前两个不同时,最多增加2个
} else {
max_add = 1; // 前两个相同时,最多增加1个
}
}
int add = min(need, max_add);
if (add == 1) {// 增量为1的情况
if (i == 1) {
// 与第一个元素不同(1→2)
a[i] = 2;
} else {
if (a[i-1] == a[i-2]) {
// 前两个相同,选一个不同的值
for (int c = 1; c <= 3; ++c) {
if (c != a[i-1]) {
a[i] = c;
break;
}
}
} else {
// 前两个不同,选与a[i-2]相同的值(与a[i-1]不同)
a[i] = a[i-2];
}
}
} else if (add == 2) {// 增量为2的情况
// 选与前两个元素都不同的值
for (int c = 1; c <= 3; ++c) {
if (c != a[i-1] && c != a[i-2]) {
a[i] = c;
break;
}
}
}
need -= add;
}
for (int num : a) {
cout << num << " ";
}
cout << "\n";
}
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
cin >> T;
while (T--) {
solve();
}
return 0;
}
D题
重要的在于知道要求欧拉函数值,即【1,b - 1】和b互质的个数
核心分析最简分数的条件转化:
1.对于分数 frac{a}{b} ,需满足:a>0,b>1 gcd(a,b)=1 l <= a+b <= r
2.关键观察:设s = a+b,则a = s-b。此时条件转化为:b的范围:2 <= b <=s-1(因为b>1且a>0,gcd(s-b, b) = 1,而gcd(s-b, b) = gcd(s, b),因此需gcd(s, b) = 1
3.欧拉函数的应用:欧拉函数表示[1, s-1]中与s互质的数的数量。对于每个s,符合条件的b的数量为value_of_ola(s) - 1(减去b=1的情况,因为b>1)。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
long long presum[N]; // 前缀和数组
int value_of_ola[N]; // 欧拉函数值
bool is_prime[N]; // 标记质数
vector<int> primes; // 存储质数
// 预处理欧拉函数、贡献值和前缀和
void init() {
// 初始化质数标记
memset(is_prime, true, sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
value_of_ola[1] = 1; // 1的欧拉函数值为1
// 线性筛计算欧拉函数,解题重点
for (int i = 2; i <= 1e6; ++i) {
if (is_prime[i]) {
primes.push_back(i);
value_of_ola[i] = i - 1; // 质数的欧拉函数值为自身减1
}
for (int p : primes) {
if (1LL *i*p > N) break;
is_prime[i * p] = false;
if (i % p == 0) {
value_of_ola[i * p] = value_of_ola[i] * p; // i是p的倍数时的欧拉函数计算
break;
} else {
value_of_ola[i * p] = value_of_ola[i] * (p - 1); // i不是p的倍数时的欧拉函数计算
}
}
}
// 计算前缀和
presum[0] = 0;
for (int s = 1; s <= N; ++s) {
if (s < 3) {
presum[s] = 0; // s<3时无有效分数
} else {
presum[s] = presum[s - 1] + (value_of_ola[s] - 1); // 注意这里,减去b==1的情况,因为b>1,分母大于1.
}
}
}
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
init();
int T;
cin >> T;
while (T--) {
int l, r;
cin >> l >> r;
cout << presum[r] - presum[l - 1] << '\n';
}
return 0;
}
还有些题作者还没a出来