Bootstrap

2021CSP-J 第二轮认证真题解析

本篇博客题解源于民间数据题目写的题解。

分糖果

题目链接

在这里插入图片描述
在这里插入图片描述

优雅的暴力👇

#include <iostream>
using namespace std;
int main()
{
    int n,l,r;
    cin>>n>>l>>r;
    int ans = n, p = 2;
    while(ans <= l) ans = n*p++;
    if(ans > r) cout<<r%n<<endl;
    else cout<<n-1<<endl;
    return 0;
}

数学O(1)

#include <iostream>
using namespace std;
int main()
{
    int n,l,r;
    cin>>n>>l>>r;
    if(r - l + 1 >= n || l%n > r%n ) cout<<n-1<<endl;
    else cout<<r%n<<endl;
    return 0;
}

插入排序

题目链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结构体 + s o r t sort sort

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 8e3 + 7;
struct node{
    int val, id;
    bool operator < (const node& t)const{
        if(val != t.val)
            return val < t.val;
        return id < t.id;
    }
};
node a[N];
int ans[N]; //ans[i] 记录第 i 个数排完序后的位置
int main()
{
    //freopen("sort.in","r",stdin);
   // freopen("sort.out","w",stdout);
    int n, q;
    cin>>n>>q;
    for(int i = 1; i <= n; i++)
    {
        int _val;
        cin>>_val;
        a[i] = {_val, i};
    }
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; i++) ans[a[i].id] = i;
    while(q--)
    {
        int op;
        cin>>op;
        if(op == 1)
        {
            int x, v;
            cin>>x>>v;
            int pos = ans[x];
            a[pos].val = v;
            //从后往前
            while(pos >= 2 && a[pos] < a[pos-1])
            {
                swap(ans[a[pos].id], ans[a[pos-1].id]);
                swap(a[pos], a[pos-1]);
                pos--;
            }
            //从前往后
            while(pos < n && a[pos+1] < a[pos])
            {
                swap(ans[a[pos+1].id], ans[a[pos].id]);
                swap(a[pos], a[pos+1]);
                pos++;
            }
        }
        else
        {
            int x;
            cin>>x;
            cout<<ans[x]<<endl;
        }
    }
    return 0;
}

网络连接

题目链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
大模拟,字符串的处理

#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
using namespace std;
set<string> server;
map<string,int> mp;
bool judge(int x, int y, int z)
{
    if(x < y || x > z) return false;
    return true;
}

bool check(string str)
{
    stringstream fin(str);
    int a, b, c, d, e;
    char x, y, z, w;
    fin>>a>>x>>b>>y>>c>>z>>d>>w>>e;
    
    if(!judge(a,0,255) || !judge(b,0,255) || !judge(c,0,255) || !judge(d,0,255) || !judge(e,0,65535))
        return false;
    if(x != '.' || y != '.' || z != '.' || w != ':') return false;
    string temp = to_string(a)+"."+to_string(b)+"."+to_string(c)+"."+to_string(d)+":"+to_string(e);
    return temp == str;
}
int main()
{
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++)
    {
        string op, str;
        cin>>op>>str;
        bool ok = check(str);
        if(op[0] == 'S')
        {
            if(!ok) cout<<"ERR"<<endl;
            else
            {
                if(server.find(str) == server.end())
                {
                    cout<<"OK"<<endl;
                    server.insert(str);
                    mp[str] = i;
                }
                else cout<<"FAIL"<<endl;
            }
        }
        else
        {
            if(!ok) cout<<"ERR"<<endl;
            else
            {
                if(server.find(str) != server.end())
                {
                    map<string,int>::iterator it;
                    for(it = mp.begin(); it != mp.end(); it++)
                    {
                        string p = it->first;
                        if(p == str)
                        {
                            cout<<it->second<<endl;
                            break;
                        }
                    }
                }
                else cout<<"FAIL"<<endl;
            }
        }
    }
    return 0;
}

小熊的果篮

题目链接
在这里插入图片描述
在这里插入图片描述
双链表,时间复杂度O(n)

#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
using namespace std;
const int N = 2e5 + 7;
int a[N]; //a[i]表示第 i 个数是 0 还是 1
int L[N]; //L[i]表示第 i 个数左边的数的编号
int R[N]; //R[i]表示第 i 个数右边的数的编号
int temp[N]; //块头编号
bool st[N]; //st[i] = true表示第 i 个数被删除

int main()
{
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++)
    {
        cin>>a[i];
        L[i] = i - 1;
        R[i] = i + 1;
    }
    L[n + 1] = n; 
    R[0] = 1;
    int id = 0;
    temp[id++] = 1;
    for(int i = 2; i <= n; i++)
        if(a[i] != a[i-1]) temp[id++] = i;
    while(L[n+1] != 0)
    {
        int cur, t = 0;
        for(int i = 0; i < id; i++)
        {
            cur = temp[i];
            if(st[cur]) continue;
            printf("%d ",cur);
            st[cur] = 1;
            R[L[cur]] = R[cur];
            L[R[cur]] = L[cur];
            
            if(R[cur] != n + 1 && (L[cur] == 0 || a[R[cur]] != a[L[cur]]))
                temp[t++] = R[cur];
        }
        id = t;
        cout<<'\n';
    }
    return 0;
}

结语

2021 CSP-J 第二轮认证题目比较小清新,没有图论和动态规划,个人感觉分数线会上涨,很考察学生的基础。如果你真的打算在信奥赛这条路上走的更远,在 CSP-J 取得好成绩不要骄傲,发挥失常也不要灰心丧气,前期只是打基础,后面的 CSP-S 以及 NOIP 才是你的主场。💪💪

;