2025CSP-J2游记

写作背景

本文写作日期是2026/9/26,昨天是中秋节,作者写下了这篇游记,为什么恰恰是今天,因为xzzf知道sgl昨天泡图书馆把作业快写完了,嘱sgl作文以忆CSP J2的事,至于xzzf和sgl是什么关系呢?那当然是鲁迅和周树人的关系了

比赛前一天

当天睌上有点失眠,突然想起承诺书忘签了。赶紧签一下

比赛当天

到了考场门前,看到机构老师,我在问以下两行代码能不能用:

1
2
ios::sync_with_stdio(false);
cin.tie(0);

老师说,你用scanf和printf就行,搞不懂不要写。
在我们之前进去校园的,是一群敬业的高中生。作者感慨道:

敬业的高中生,周六还得来上课

进到了考场,我们把东西放在考场外面,有一个在密码的压缩包,但具体情况作者不记得了,有可能是说是可以看到四道题目的题目英语名称,也有可能是打开的时候就需要输入密码了。(作者,这个地方建议各位把密码输入完过后,复制粘贴一下,如果说你没操作好,输两次密码的话,这个能帮你省一点时间)。
考试开始前几分钟压缩包密码发下来了。

T1

简单sort一下解决

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include<bits/stdc++.h>
using namespace std;
bool cmp(char x,char y)
{
    return x>y;
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    string s,s1;
    cin>>s;
    long long len=s.size();
    for(int i=0;i<len;i++)
    {
        if('0'<=s[i]&&s[i]<='9') s1+=s[i];
    }
    sort(s1.begin(),s1.end(),cmp);
    cout<<s1;
    return 0;
}

T2

我们注意到输出与输入相反,这题 $n \times m = 100 \le 10^8$,就枚举吧

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll s[110],r;
bool cmp(ll x,ll y)
{
    return x>y;
}
int main()
{
    freopen("seat.in","r",stdin);
    freopen("seat.out","w",stdout);
    ll n,m;
    cin>>n>>m>>r;
    s[1]=r;
    for(int i=2;i<=n*m;i++) cin>>s[i];
    sort(s+1,s+n*m+1,cmp);
    for(int i=1;i<=n*m;i++)
    {
        if(s[i]==r)
        {
            r=i;
            break;
        }
    }
    ll cnt=0;
    for(int i=1;i<=m;i++)
    {
        if(i%2!=0)
        {
            for(int j=1;j<=n;j++)
            {
                cnt++;
                if(cnt==r)
                {
                    cout<<i<<" "<<j;
                    return 0;
                }
            }
        }
        else{
            for(int j=n;j>=1;j--)
            {
                cnt++;
                if(cnt==r)
                {
                    cout<<i<<" "<<j;
                    return 0;
                }
            }
        }
    }
    return 0;
}

T3

题目说异或,上节课正好讲了,性质A简单,性质B也简单(实际写错一半),下一题。
(细节忘写暴力)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll s[500010];
int main()
{
    freopen("xor.in","r",stdin);
    freopen("xor.out","w",stdout);
    ll n,k;
    cin>>n>>k;
    ll s0=0,s1=0;
    for(int i=1;i<=n;i++)
    {
        cin>>s[i];
        if(s[i]==0) s0++;
        else if(s[i]==1) s1++;
    }
    if(s0==n)
    {
        if(k==0) cout<<n/2;
        else if(k==1) cout<<n;
        else cout<<0;
    }
    else if(s0+s1==n)
    {
        if(k==0) cout<<s0+s1/2;
        else if(k==1) cout<<s1;
    }
    else cout<<2;
    return 0;
}

T4

一看$n \le 20$ ,我就想到一轮前因为感兴趣读的子集枚举,我还真写出来了!爽吃40pts。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Pow(ll a,ll b)
{
    ll sum=1;
    while(b--)
    {
        sum*=a;
    }
    return sum;
}
ll s[5010];
int main()
{
    freopen("polygon.in","r",stdin);
    freopen("polygon.out","w",stdout);
    ll n,s1=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>s[i];
        if(s[i]==1) s1++;
    }
    if(s1==n)
    {
        ll sum=0;
        for(int i=3;i<=n;i++)
        {
            sum+=((n-i+2)*(n-i+1)/2)%998244353;
        }
        cout<<sum%998244353;
    }
    else if(n<=22)
    {
        ll z=Pow(2,n),cnt=0;
        for(int i=7;i<=z;i++)
        {
            ll z1=i,maxn=0,sum=0,p=n;
            while(z1)
            {
                if(z1%2==1)
                {
                    sum+=s[p];
                    maxn=max(maxn,s[p]);
                }
                p--;
                z1=(z1>>1);
            }
            if(sum>maxn*2)
            {
                cnt=(cnt+1)%998244353;
            }
        }
        cout<<cnt;
    }
    else cout<<2344255;
    return 0;
}

最终总分:100+100+20+40=260pts
一等线:257pts
卡线一等了


这次比赛告诉我两个道理:
一:记得要写暴力。
第3题中:
本次比赛我的T3我的得分:20pts
$O(n^3)$ : 40pts
前缀异或和$O(n^2)$ :60pts。
二:多看书,万一考到了呢