• 第五届太原理工大学程序设计竞赛新生赛(初赛)题解


    第五届太原理工大学程序设计竞赛新生赛(初赛)题解

    时隔半年重做一次,还是有几道不会,,,,,

    ⭐️A.饿饿饭饭

    题目:

    在这里插入图片描述

    🌟题解:

    很简单,签个到输出谁饿了

    代码:

    #include
    using namespace std;
    int main()
    {
        string s; cin>>s;
        cout<<s<<":eeff";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ⭐️B.扣点点

    题目:
    在这里插入图片描述

    🌟题解:

    hammer喜欢玩扣点点但太菜了理不清牌(doge),让你帮忙按一定顺序整理,典型的排序吧

    代码:

    1.这种字符串数组排序较为简单
    #include 
    #include 
    using namespace std;
    const int N = 15;
    string s[N];
    int main()
    {
        int n; cin>>n;
        for(int i = 0;i<n;i++)   
        {
            char j[2];
            cin>>j[1]>>j[0];
            s[i] += j[0];
            s[i] += j[1];
        }
        sort(s,s+n);
        for(int i = 0;i<n;i++)  
        {
            cout<<s[i][1]<<s[i][0]<<' ';
        }
        return 0;
    }
    2.标记法
    #include 
    using namespace std;
    const int N = 15;
    int cnt[4][10]; 
    int main() {
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            int num;
            char s;
            cin >> num >> s;
            int id;
            if (s == 'B') id = 0;
            else if (s == 'C') id = 1;
            else id = 2;
            cnt[id][num]++;
        }
        for (int i = 0; i < 3; ++i) { 
            for (int j = 1; j <= 9; ++j) {
                for (int k = 0; k < cnt[i][j]; ++k) { //可能这里不好理解,就是看k+到比cnt这大就是cnt-反过来也可以写成while(cnt[i][j]--&&cnt>0)
                    cout << j << (i==0 ? 'B' : i==1 ? 'C' : 'D') << " "; 
                }
            }
        }
        cout << endl;
        return 0;
    }
    3.自己写个结构体排序
    #include
    using namespace std;
    int n;
    struct node{
        char x,y;
    }a[15];
    bool cmp(node q,node p){
        if(q.y!=p.y)return q.y<p.y;
        else return q.x<p.x;
    }
    string s;
    int main(){
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>s;
            a[i].x=s[0];
            a[i].y=s[1];
        }
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++){
            cout<<a[i].x<<a[i].y<<" ";
        }
    }
    4.利用mulimap性质(某孙神的)
    #include 
    using namespace std;
    int main(){
        multimap<char,char>mp;
        multimap<char,char>ans;
        int n;
        cin>>n;
        while(n--){
            char ch;
            char temp;
            cin>>temp>>ch;
            mp.insert({temp,ch});
        }
        for(auto it=mp.begin();it!=mp.end();it++){
            ans.insert(pair<char,char>(it->second,it->first));
        }
        for(auto it=ans.begin();it!=ans.end();it++){
            cout<<it->second<<it->first<<" ";
        }
        return 0;
    }
    
    • 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
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    ⭐️String problem

    题目:

    在这里插入图片描述

    🌟题解:

    也很简单的一道,比较三个字符串字符就行,2个一样就改一次,都不一样就改两次,

    代码:

    #include
    using namespace std;
    int n;
    string s1,s2,s3;
    int ans;
    int main()
    {
        cin>>n;
        cin>>s1>>s2>>s3;
        for(int i=0;i<n;i++)
        {
            if(s1[i]==s2[i] && s1[i]==s3[i]) continue;
            else if(s1[i]==s2[i] || s1[i]==s3[i] || s2[i]==s3[i]) ans++;
            else ans+=2;
        }
        cout<<ans<<endl;  
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    ⭐️D.数豆豆

    题目:

    在这里插入图片描述

    🌟题解:

    考察一下思维吧,其实也很简单,就是每次拿大的数字,排下序就好了

    代码:

    #include 
    #include 
    #include
    using namespace std;
    int main()
    {
        string s;
        cin>>s;
        sort(s.begin(),s.end());
        reverse(s.begin(),s.end());
        string s1,s2;
        for(int i=0;i<s.size();++i)
        {
            if(i%2==0)
                s1=s1+s[i];
            else
                s2=s2+s[i];
        }
        if(s1[0]=='0')    s1="0";
        if(s2[0]=='0')    s2="0";
        cout<<s1<<endl;
        cout<<s2<<endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    ⭐️E.Another string problem

    题目:

    在这里插入图片描述

    🌟题解:

    也是挺简单的,呆梨同学们都可以报名新生赛体验今年12月。就判断下是否两个字符串只有一个字符不一样就行,注意中间缺字符或者多字符也是可以的,那么就有三种情况,字符一样长,不一样长是删除还是增加(差距为1),还有差距大于1了因为只能改一次肯定不行。

    代码:

    #include
    using namespace std;
    int main() {
        string s, t;
        cin >> s ; cin>>t;
        int n = s.size(), m = t.size();
        if (abs(n-m) > 1) cout << "NO" << endl;
        else if (n == m) {
            int cnt = 0;
            for (int i = 0; i < n; ++i)
                if (s[i] != t[i] && ++cnt > 1) {
                    cout << "NO" << endl; return 0;
                }
            cout << "YES" << endl;
        } else { 
            int i, j,cnt=0;
            for (i = 0, j = 0; i < n && j < m; ++i, ++j) {
                if (s[i] != t[j]) {
                    if (n > m) --j;
                    else --i;
                    if (++cnt > 1) {
                        cout << "NO" << endl; return 0;
                    }
                }
            }
            if (i < n || j < m) ++cnt;
            cout << (cnt == 1 ? "YES" : "NO") << endl;
        }
        return 0;
    }
    
    • 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

    ⭐️F.迷失的Syuggie

    题目:
    在这里插入图片描述

    🌟题解:

    也是一道典型的bfs

    网格由字符的二维数组"f"表示,其中"#“表示障碍物,”."表示空白格子。算法从起始点(标记为’S’)开始,探索所有可能的路径,直到达到目标点(标记为’T’)或者在给定的步数限制"k"内探索完所有可能的路径。最短路径长度存储在变量"ans"中,每当找到一条更短的路径时,它就会被更新。最后,最短路径长度被打印出来。

    代码:

    #include 
    #include 
    using namespace std;
    const int N=1010;
    typedef pair<int,int> PII;
    struct point {
        int x,y,step;
    };
    queue<point> q;
    char f[N][N];
    int x[]={-1,0,1,0},y[]={0,1,0,-1};
    int n,m,k;
    int sx,sy,tx,ty;
    int ans=1e6;
    int bfs()
    {
        q.push({sx,sy,0});
        f[sx][sy]='#';
        while(q.size())
        {
            auto t=q.front();
            q.pop();
            if(t.step<=k) 
            {
                ans=min(ans,abs(t.x-tx)+abs(t.y-ty));
    
            }
            for(int i=0;i<4;i++)
            {
                int a=t.x+x[i],b=t.y+y[i];
                if(a>=1&&a<=n&&b>=1&&b<=m&&f[a][b]!='#')
                {
                    q.push({a,b,t.step+1});
                    f[a][b]='#';
                }
            }
        
        }
        return ans;
    }
    int main()
    {
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                char c;
                cin>>c;
                if(c=='T')
                {
                    tx=i;
                    ty=j;
                }
                else if(c=='S')
                {
                    sx=i;
                    sy=j;
                }
                f[i][j]=c;
            }
        cout<<bfs()<<endl;
        return 0;
    }
    
    • 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
    • 60
    • 61
    • 62
    • 63

    ⭐️G.寻找签到题之路

    题目:

    在这里插入图片描述

    🌟题解:

    一眼典型背包dp,直接写就好。。。。就是时间有限要得分最大,每个题目时间也知道。总时间就是背包,每个题目分数就是价值,时间就是重量。不过也有大佬别的做法

    代码:

    1.
    #include
    using namespace std;
    const int N = 10010;
    int t[N],s[N];    
    int f[N][N];  
    int main() 
    {
        int n, m;   
        cin >> n >> m;
        for(int i = 1; i <= n; i++) 
            cin >> s[i] >> t[i];
        for(int i = 1; i <= n; i++) 
            for(int j = 1; j <= m; j++)
            {
                if(j < t[i]) 
                    f[i][j] = f[i - 1][j];
                else    
                    f[i][j] = max(f[i - 1][j], f[i - 1][j - t[i]] + s[i]);
            }           
        cout << f[n][m] << endl;
        return 0;
    }//正的
    #include
    using namespace std;
    const int N = 1000005;
    int n,m;
    int f[N];
    int v,w;
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>w>>v;
            for(int j=m;j>=v;j--)
            {
                f[j]=max(f[j],f[j-v]+w);
            }
        }
        cout<<f[m]<<endl;
        return 0;
    }//逆的
    2.dfs来自dy
    #include
    using namespace std;
    int t, n;
    int s[21], ti[21];
    int maxn;
    void dfs(int time, int score, int tit) {
        if (time <0)return;
        if (tit == n){
            maxn = max(maxn, score);
            return;}
        dfs(time,score,tit+1);
        dfs(time-ti[tit],score+s[tit],tit+1);
        return;
    }
    int main() {
        cin >> n >> t;
        for (int i = 0; i < n; i++) {
            cin >> s[i] >> ti[i];
        }
        dfs(t, 0, 0);
        cout << maxn;
    }
    
    • 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
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    ⭐️H.子矩阵和

    题目:

    在这里插入图片描述

    🌟题解:

    就是典型的二维前缀和处理一下查询

    代码:

    #include
    using namespace std;
    typedef long long ll;
    const int N=10010;
    ll a[N],b[N],c[N][N],s[N][N];
    int main()
    {
        ll n,m,q;
        cin>>n>>m;
        for(ll i=1;i<=n;i++)
            cin>>a[i];
        for(ll i=1;i<=m;i++)
            cin>>b[i];
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
                c[i][j]=a[i]*b[j];
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
                 s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + c[i][j];
        cin>>q;
        while(q--)
        {
            ll x1,y1,x2,y2;
            cin>>x1>>y1>>x2>>y2;
            cout<<s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]<<endl;
        }
        return 0;
    }
    
    • 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

    ⭐️I.最短区间

    题目:
    在这里插入图片描述

    🌟题解:

    双指针i,j指一指循环区间根据条件找到最小区间

    代码:

    1.
    #include
    using namespace std;
    const int N = 100005;
    typedef long long ll;
    ll n,x;
    ll a[N];
    ll mul=1,ma;
    int ans=N;
    int main()
    {
        cin>>n>>x;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1,j=1;i<=n;i++)
        {
            while(mul<x && j<=n)
            {
                mul*=a[j];j++;
            }
            if(mul>=x) ans=min(ans,j-i);
            mul/=a[i];
        }
        if(ans>n) ans=-1;
        cout<<ans<<endl;
        return 0;
    }
    2.
    #include 
    using namespace std;
    const int N = 1e5 + 5;
    int a[N];
    int main() {
        int n, x;
        cin >> n >> x;
        for (int i = 1; i <= n; ++i)
            cin >> a[i];
        int left = 1, right = 1, len = 0;
        long long prod = a[1];
        while (right <= n) {
            if (prod >= x) { 
                if (len == 0 || right - left + 1 < len) 
                    len = right - left + 1;
                prod /= a[left]; 
                left++;
                if (left > right) { 
                    right++;
                    if (right <= n)
                        prod *= a[right];
                }
            } else {
                right++;
                if (right <= n)
                    prod *= a[right];
            }
        }
        if (len == 0)
            cout << "-1" << endl;
        else
            cout << len << endl;
        return 0;
    }
    
    • 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
    • 60
    • 61

    ⭐️J.点球大战

    题目:
    在这里插入图片描述

    🌟题解:

    代码:


    ⭐️K.冠军预言

    题目:
    在这里插入图片描述

    🌟题解:

    代码:


    ⭐️L.an interesting problem

    题目:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    🌟题解:

    很复杂的一道题但是思维很简单,代码量很多

    代码:


    ⭐️M.选数异或

    题目:

    在这里插入图片描述

    🌟题解:

    我们可以用一个桶来记录每个数出现的次数,然后从前往后遍历数列,对于每个数 x,我们可以计算出在它之前出现的比它大的数的个数,就是(i-1-cnt[x]),其中 i 是当前遍历到的位置,cnt[x] 是 x* 出现的次数。这个式子的意思是,在 x 之前,一共有 i−1 个数,其中有 cnt[x] 个数等于 x,所以比 x大的数的个数就是 i−1−cnt[x]。

    最后的答案就是所有的逆序对个数之和。时间复杂度 O*(*n)。

    代码:

    #include
    using namespace std;
    const int N = 1000010;
    typedef long long ll;
    ll n,cnt[N],x,ans;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) 
        {
            cin>>x;
            ans+=(i-1-cnt[x]);
            cnt[x]++;
        }
        cout<<ans<<endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    A

  • 相关阅读:
    git多人协作开发
    串口通信及串口转蓝牙相关知识
    SQL教学: MySQL进阶操作详解--探索DML语句的高级用法
    yarn命令详细解读
    使用分形思想,通过图灵完备的机器赛跑关卡,并获得小机快跑成就
    怎么用CSS画一个爱心?
    manjaro gnome 记录 3 配置国内镜像源
    session伪造
    Servlet运行原理_API详解_请求响应构造进阶之路(Servlet_2)
    信创环境下Nginx正向代理实现内网发送邮件
  • 原文地址:https://blog.csdn.net/A2105153335/article/details/133967968