CSP-J 2023 赛前模拟赛 Day 2 比赛复盘
CSP-J 2023 赛前模拟赛 Day 2 比赛复盘
总分:$70+50+10+20=150$
分析:
T1:
第一题是一道比较
难简单的模拟题,主要考验优化(周期优化)。暴力 70 分
AC Code:
#include <cstdio>
#include <cstring>
using namespace std;
char s[10003], c[10003];
int main()
{
    int m;
    scanf("%s%d", s + 1, &m);
    while(m--)
    {
        int l, r, k;
        scanf("%d%d%d", &l, &r, &k);
        int len = r - l + 1;
        k %= len;
        for(int j = l; j <= r; ++j)
            if(j - k < l)
                c[j] = s[j - k + len];
            else
                c[j] = s[j - k];
        for(int j = l; j <= r; ++j)
            s[j] = c[j];
    }
    printf("%s", s + 1);
    return 0;
}T2:
第二题是一道贪心题,和 不相交线段 类似。核心思路是对课程的开始时间进行升序排序,然后贪心地判断结束时间是否超越开始时间。
AC Code:
#include <cstdio>
#include <algorithm>
using namespace std;
using PII = pair<int, int>;
PII a[100003];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d%d", &a[i].first, &a[i].second);
    sort(a + 1, a + n + 1);
    PII x{a[1].second, 1};
    for(int i = 2; i <= n; ++i)
        if(a[i].second >= x.first)
            x = {a[i].second, x.second + 1};
    printf("%d", n - x.second);
    return 0;
}T3:
第三题是一道洪水填充算法的题目。洪水填充算法,简而言之就是通过 DFS/BFS 检测一块连续的面积,更多内容请 BDFS。
AC Code:
#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int N = 1003;
vector<int> a;
set<int> st;
bool b[N][N];
char s[N][N];
int f[N][N], n, m, cnt = 0;
void flood(const int &x, const int &y)
{
    if(x < 1 || x > n || y < 1 || y > m || b[x][y] || s[x][y] == '*')
        return;
    b[x][y] = true;
    ++a[cnt];
    f[x][y] = cnt;
    flood(x + 1, y);
    flood(x - 1, y);
    flood(x, y + 1);
    flood(x, y - 1);
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%s", s[i] + 1);
    a.push_back(0);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            if(s[i][j] == '.' && !b[i][j])
            {
                a.push_back(0);
                ++cnt;
                flood(i, j);
            }
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
            if(s[i][j] == '.')
                putchar(s[i][j]);
            else
            {
                int d = 1;
                st.insert(f[i + 1][j]);
                st.insert(f[i - 1][j]);
                st.insert(f[i][j + 1]);
                st.insert(f[i][j - 1]);
                for(const auto &y: st)
                    d += a[y];
                printf("%d", d % 10);
                st.clear();
            }
        printf("\n");
    }
    return 0;
}T4:
第四题是一道字符串 DFS 题。其中前 $60\%$ 的数据可以通过
打表预处理获得。满分做法是,DFS 当前数位的下一步选择。(写了 $154$ 行,肝差点废了)
AC Code:
#include <iostream>
#include <string>
using namespace std;
int m;
string n, ans;
void solve(const int &x)
{
    if(x > m)
    {
        for(int _ = 0; _ < x / 2; ++_)
            ans += '4';
        for(int _ = 0; _ < x / 2; ++_)
            ans += '7';
        return;
    }
    int cnt4 = 0, cnt7 = 0, idx = 0, lcnt4 = 0, lcnt7 = 0;
    for(int i = 0; i < x; ++i)
        if(n[i] < '4')
        {
            for(; cnt4 < x / 2; ++cnt4)
                ans += '4';
            for(; cnt7 < x / 2; ++cnt7)
                ans += '7';
            return;
        }
        else if(n[i] == '4')
            if(cnt4 < x / 2)
            {
                if(cnt7 < x / 2)
                {
                    idx = i;
                    lcnt4 = cnt4;
                    lcnt7 = cnt7;
                }
                ans += '4';
                ++cnt4;
            }
            else
            {
                for(; cnt7 < x / 2; ++cnt7)
                    ans += '7';
                return;
            }
        else if(n[i] < '7')
            if(cnt7 < x / 2)
            {
                ans += '7';
                ++cnt7;
                for(; cnt4 < x / 2; ++cnt4)
                    ans += '4';
                for(; cnt7 < x / 2; ++cnt7)
                    ans += '7';
                return;
            }
            else
            {
                i = idx;
                cnt4 = lcnt4;
                cnt7 = lcnt7;
                ans = ans.substr(0, cnt4 + cnt7);
                ans += '7';
                ++cnt7;
                for(; cnt4 < x / 2; ++cnt4)
                    ans += '4';
                for(; cnt7 < x / 2; ++cnt7)
                    ans += '7';
                return;
            }
        else if(n[i] == '7')
            if(cnt7 < x / 2)
            {
                ans += '7';
                ++cnt7;
            }
            else
            {
                i = idx;
                cnt4 = lcnt4;
                cnt7 = lcnt7;
                ans = ans.substr(0, cnt4 + cnt7);
                ans += '7';
                ++cnt7;
                for(; cnt4 < x / 2; ++cnt4)
                    ans += '4';
                for(; cnt7 < x / 2; ++cnt7)
                    ans += '7';
                return;
            }
        else
        {
            i = idx;
            cnt4 = lcnt4;
            cnt7 = lcnt7;
            ans = ans.substr(0, cnt4 + cnt7);
            ans += '7';
            ++cnt7;
            for(; cnt4 < x / 2; ++cnt4)
                ans += '4';
            for(; cnt7 < x / 2; ++cnt7)
                ans += '7';
            return;
        }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n;
        m = n.size();
        if(m & 1)
        {
            solve(m + 1);
            cout << ans << "\n";
            ans.clear();
            continue;
        }
        for(int i = 0; i < m / 2; ++i)
            if(n[i] < '7')
            {
                solve(m);
                break;
            }
            else if(n[i] > '7')
            {
                solve(m + 2);
                break;
            }
        if(ans.empty())
            for(int i = m / 2; i < m; ++i)
                if(n[i] < '4')
                {
                    solve(m);
                    break;
                }
                else if(n[i] > '4')
                {
                    solve(m + 2);
                    break;
                }
        if(ans.empty())
            solve(m);
        cout << ans << "\n";
        ans.clear();
    }
    return 0;
}总的来说这次的难度还算简单,前三题完全有能力 AC 的。第四题则是比较难,需要熟练运用 DFS 技术。
总结:
这次只拿到 $150$ 分,发挥失常。T1 没有想到优化特别不应该;T2 没有想到贪心也不应该;T3 没有想到洪水填充算法还可以接受,但是下次遇到这种题目一定要想起来;T4 已解决。
签名:
$TigerTanWQY$
日期:
$2023.10.03$

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号