CSP J 2025
zengyukai2012 · · 个人记录
CSP J 2025
T1 拼数 / number
这道题是模拟题,由于
#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
这道题可以模拟,也可以当作数学题,对于这一列中是第几个,可以计算
#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
这道题可以发现前缀异或和,即:
:::info[前缀异或和]
定义
所以可以想要在前面的所有前缀异或和中查找第一个
#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;
}
但是实际测试中,只有
考虑优化,发现每次的“决策集合”都只会进行两种操作:
- 插入一个数
qzh_i - 清空
所以考虑使用 set 和二分查找维护。
由此得到
#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;
}
然而我当时没想起来 find 方法,于是使用了 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;
}
同样可以
然而我考场时忘记判断 if (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
考场上这道题还剩越
#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;
}