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,r)我不是暴力模拟,用的是数学公式,我们观察图片可以研究出不难得出: 列c就是(小R所在位置/行数)向上取整\ 列r有两种情况,奇数列和偶数列。 奇数列是 t mod n,\ 偶数列 n-t mod n+1。

#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;

1的数量 ; &k=1\\ 自己思考,这里不给出了. & k=0 \end{array}\right.

部分代码:

#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){
        ?
    }
    //下面是暴搜代码,只能过样例,有一些问题,过不了,就不写了
}
update \times 1

第四题

我菜,只有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;
}

感谢观看,制作不易,留个赞吧,欢迎讨论