CSP-J2025个人记录+部分题解
考完后不得不承认我是个菜鸡,估分210~260,具体还要在估,但收货还是有很多的,一下分享一些我的策略、思路和还原代码(看了一下别人的游记,都 e…… 一言难尽,只有我想写个流水账吗?)
::::warning[注意:]{open} 本内容只用于研究结果交流目的。内容不一定正确,具体以官方为准,如有建议欢迎指出,谢谢! Thanks♪(・ω・)ノ ::::
开始准备
先看一遍考生须知,准备解压密码,今年密码很有意思J和S分别是上善若水、人杰地灵。
开考后先简单浏览题目,一二题较简单,三四题考虑到我能力有限 (就是菜)可以骗分。
第一题:
比较简单的字符串处理+模拟,不详细展开了,耗时约20分钟(个人比较谨慎,速度较慢)
以下贴上代码(别抄啊,不给全):
#include<bits/stdc++.h>
using namespace std;
string s;
char a[1000005];//存储答案
int n,t=0;
bool cmp(char a,char b){//排序比较函数(应该不需要讲了吧)
?;
}
int main(){
cin>>s;
n=s.size();
for(int i=0;i<n;i++){
if('0'<=s[i]&&s[i]<='9'){//如果是数字
t++;
存储答案;
}
}
sort(?,?,?);//将数字从大到小排列组成一个数
for(int i=1;i<=t;i++){//输出答案
cout<<?;
}
}
第二题:
第二题我是用的是模拟排序+数学公式。\
一开始先输入,这里考虑使用结构体以记录 小R的位置(当然也有其他方法,欢迎讨论)然后排序,\
再找到小R的位置并记录(我这里是从1开始的)\
接着就是求出实际位置可以研究出不难得出:
列c就是
#include<bits/stdc++.h>
using namespace std;
int n,m,c,r,t;
struct N{
int a,i;
}p[105];
bool cmp(N A,N B){
return A.a>B.a;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n*m;i++){
cin>>p[i].a;
p[i].i=i;
}
sort(?);
for(int i=1;i<=n*m;i++){
if(是小R){
t=i;
break;
}
}
//推导出的数学公式
c=ceil(1.0*t/n);
r=t%n;
if(r==0){
r=n;
}
if(c%2==0){
r=n-r+1;
}
cout<<c<<" "<<r;
}
第三题
第三题我考虑到我的能力采用骗分策略,这里就讲讲给蒟蒻的骗分方法指导,不建议大佬观看。\ 主要点在测试点上,观察下面测试点分布,不难看出性质A、B是个很好的突破口
【数据范围】
对于所有测试数据,保证:
- 对于所有
1 \leq i \leq n ,均有0 \leq a_i < 2^{20} 。 ::cute-table{tuack} | 测试点编号 |n \leq |k | 特殊性质 | | :--: | :--: | :--: | :--: | |1 |2 |=0 | A | |2 |10 |\leq 1 | B | |3 |10^2 |=0 | A | |4, 5 | ^ |\leq 1 | B | |6 \sim 8 | ^ |\leq 255 | C | |9, 10 |10^3 | ^ | ^ | |11, 12 | ^ |< 2^{20} | 无 | |13 |2 \times 10^5 |\leq 1 | B | |14, 15 | ^ |\leq 255 | C | |16 | ^ |< 2^{20} | 无 | |17 |5 \times 10^5 |\leq 255 | C | |18 \sim 20 | ^ |< 2^{20} | 无 |特殊性质 A: 对于所有
1 \leq i \leq n ,均有a_i = 1 。特殊性质 B: 对于所有
1 \leq i \leq n ,均有0 \leq a_i \leq 1 。特殊性质 C: 对于所有
1 \leq i \leq n ,均有0 \leq a_i \leq 255 。特殊性质A可简单得出,
ans=n/2 \ 特殊性质B分两种情况,为k=1和k=0;
部分代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[500005],k;
int main(){
cin>>n>>k;
bool A=1,B=1;
int cnt1=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1)cnt1++;
if(A!=0&&?)A=0;
if(B!=0&&?)B=0;
}
if(A){
cout<<n/2;
return 0;
}
if(B&&k==1){
cout<<cnt1;
return 0;
}
if(B&&k==0){
?
}
//下面是暴搜代码,只能过样例,有一些问题,过不了,就不写了
}
第四题
我菜,只有40分代码。暴力出奇迹。深搜暴力,没啥好讲的,直接上代码(这次不藏了,别抄啊):
#include<bits/stdc++.h>
using namespace std;
int n,a[5005],m,vis[5005];
long long ans;
const int mod=998244353;
void dfs(int k,int v){
if(k>m){
int t=0,maxn=0;
for(int i=1;i<=m;i++){
t+=vis[i];
maxn=max(maxn,vis[i]);
}
if(t>maxn*2){
ans++;
}
return;
}
for(int i=v+1;i<=n-(m-k);i++){
vis[k]=a[i];
dfs(k+1,i);
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(m=3;m<=n;m++){
dfs(1,0);
ans=ans%mod;
}
cout<<ans;
}