专栏文章
CSP J 2025
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minawlud
- 此快照首次捕获于
- 2025/12/01 23:25 3 个月前
- 此快照最后确认于
- 2025/12/01 23:25 3 个月前
CSP J 2025
T1 拼数 / number
这道题是模拟题,由于 ,所以 ,不会超时,直接暴力,考场代码如下:
CPP#include <bits/stdc++.h>
using namespace std;
string s, s1;
bool cmp(char l, char r)
{
return l > r;
}
int main()
{
freopen("number.in", "r", stdin);
freopen("number.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> s;
for (size_t i = 0; i < s.size(); ++i)
if ('0' <= s[i] && s[i] <= '9') // 判断是否是数字
s1.push_back(s[i]);
sort(s1.begin(), s1.end(), cmp); // 倒序排序
cout << s1 << '\n';
return 0;
}
T2 座位 / seat
这道题可以模拟,也可以当作数学题,对于这一列中是第几个,可以计算 ( 表示排名),考场代码如下:
CPP#include <bits/stdc++.h>
using namespace std;
int n, m, rnk = 1;
int a[101];
int t, tt;
int main()
{
freopen("seat.in", "r", stdin);
freopen("seat.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
cin >> a[1]; //输入小 R 成绩
for (int i = 2; i <= n * m; ++i) // 输入其他人成绩
{
cin >> a[i];
if (a[i] > a[1]) // 统计排名
++rnk;
}
t = (rnk + n - 1) / n; // 列
tt = (rnk - 1) % n + 1; // 第几个
if (t % 2 == 1)
cout << t << ' ' << tt << '\n';
else
cout << t << ' ' << n - tt + 1 << '\n';
return 0;
}
T3 异或和 / xor
这道题可以发现前缀异或和,即:
前缀异或和
定义 ,其中 ,则 (因为异或的逆运算是它本身)。
所以可以想要在前面的所有前缀异或和中查找第一个 (,其中 表示上一个区间的结尾),容易写出代码:
CPP#include <bits/stdc++.h>
using namespace std;
int n, k;
int a[500001];
int qzh[500001];
int lst = 0; // 上一个区间结尾
int s = 0;
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i) // 计算前缀异或和
qzh[i] = qzh[i - 1] ^ a[i];
for (int i = 1; i <= n; ++i)
for (int j = lst; j < i;++j) // 枚举每个区间 j + 1...i
if ((qzh[j] ^ qzh[i]) == k) // 判断
{
++s;
lst = i;
break;
}
cout << s << '\n';
return 0;
}
但是实际测试中,只有 分()。
考虑优化,发现每次的“决策集合”都只会进行两种操作:
- 插入一个数
- 清空
所以考虑使用
set 和二分查找维护。由此得到 代码:
CPP#include <bits/stdc++.h>
using namespace std;
int n, k;
int a[500001];
int qzh[500001];
int ans, lst;
set<int> t;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
qzh[i] = qzh[i - 1] ^ a[i];
t.insert(0);
for (int i = 1; i <= n; ++i)
{
set<int>::iterator fd = t.find(qzh[i] ^ k);
if (fd != t.end())
{
t.clear();
lst = i;
++ans;
}
t.insert(qzh[i]);
}
cout << ans << '\n';
return 0;
}
然而我当时没想起来
CPPfind 方法,于是使用了 lower_bound 代替:#include <bits/stdc++.h>
using namespace std;
int n, k;
int a[500001];
int qzh[500001];
int ans, lst;
set<int> t;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
qzh[i] = qzh[i - 1] ^ a[i];
t.insert(0);
for (int i = 1; i <= n; ++i) // 浠?i 涓虹粨灏?
{
set<int>::iterator fd = t.lower_bound(qzh[i] ^ k);
if (fd != t.end())
if (*fd == (qzh[i] ^ k))
{
t.clear();
lst = i;
++ans;
}
t.insert(qzh[i]);
}
cout << ans << '\n';
return 0;
}
同样可以 。
然而我考场时忘记判断
CPPif (fd != t.end()),喜提 分。考场代码:#include <bits/stdc++.h>
using namespace std;
int n, k;
int a[500001];
int qzh[500001];
int ans, lst;
set<int> t;
int main()
{
freopen("xor.in", "r", stdin);
freopen("xor.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
qzh[i] = qzh[i - 1] ^ a[i];
for (int i = 1; i <= n; ++i) // 以 i 为结尾
{
t.insert(qzh[i - 1]);
set<int>::iterator fd = t.lower_bound(qzh[i] ^ k);
if (*fd == (qzh[i] ^ k))
{
t.clear();
lst = i;
++ans;
}
}
cout << ans << '\n';
return 0;
}
T4 多边形 / polygon
考场上这道题还剩越 ,没想出正解,写了暴力。考场代码:
CPP#include <bits/stdc++.h>
using namespace std;
int n, ans;
int a[50001];
void dfs(int now, int lst, int s, int yx)
{
if (now == n + 1)
{
if (yx >= 3)
if (s > a[lst] * 2)
++ans;
return;
}
dfs(now + 1, now, s + a[now], yx + 1);
dfs(now + 1, lst, s, yx);
}
int main()
{
freopen("polygon.in", "r", stdin);
freopen("polygon.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i];
sort(a + 1, a + 1 + n);
dfs(1, 0, 0, 0);
cout << ans << '\n';
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...