桂林信息科技学院第一届程序设计大赛完整题解 C++

Posted iuk11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了桂林信息科技学院第一届程序设计大赛完整题解 C++相关的知识,希望对你有一定的参考价值。

目录

A.Hello 小明

本题作为本场最简单的签到题,改编于hello world,想考察大家的字符串输入输出能力。

#include<bits/stdc++.h>
using namespace std;
int main()
    string s;
    cin>>s;
    cout<<"Hello "<<s<<endl;
    return 0;

B.博学多识的小明

匹配句子中出现的Abandon/abandon,因为有空格,在c++中使用getline将整体一行读入。因为不需要考虑后缀,也可以根据空格将字符串分成一个一个单独的单词或标点。
我这里给出,直接去遍历整行句子,遇到A或者a就进入判断,判断下一个是否为b,下下个是否为a,以此类推。特别的,为了减小难度,整个单词如果前缀不满足,那么就不可能出现该单词后缀包含abandon的情况。

#include<bits/stdc++.h>
using namespace std;
string t="abandon";
int ans;
int main()
    string s;
    getline(cin,s);
    for(int i=0;i<s.size();i++)
        if(s[i]==t[0]||s[i]=='A')
            int idx=i;
            for(int j=1;j<=6;j++)
                if(s[++i]==t[j]) ;
                else
                    i=idx;
                    break;
                
            
            if(i!=idx)
                ans++;
            
        
    
    cout<<ans<<endl;
    return 0;

C.小明爱偶数

题目挺唬人,但是理清楚题意后很简单。
题目意思为给定一个 n n n ,可以倒置它的一个从起始位置开始的子区间,使得最终该数变成一个偶数。
最终的结果集为 − 1 , 0 , 1 , 2 \\-1,0,1,2\\ 1,0,1,2 。我们读题后不难发现如果能翻转成偶数,那么最多两次一定能实现。第一次以该位偶数为结尾,倒置,将该位变成首位,然后再整体倒置,将该位变成最后一位。

  • n n n 的每一位都是奇数时,结果为 -1
  • if n n n 的末位为偶数时,结果为0
  • else if n n n 的首位是偶数时,结果为1
  • else if n n n 的某一位置为偶数时,结果为2
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
    int t;
    cin>>t;
    while(t--)
        ll n;
        cin>>n;
        if(n%2==0) cout<<0<<endl;
        else
            vector<int> ve;
            while(n)
                int tem=n%10;
                ve.push_back(tem);
                n/=10;
            
            int ans=-1;
            for(int i=ve.size()-1,j=1;i>=0;i--,j++)
                if(ve[i]%2==0)
                    ans=j;
                    break;
                
            
            if(ans>=2) ans=2;
            cout<<ans<<endl;
        
    
    return 0;

D.小明爱打单词

又是一道题目挺唬人,但是理清楚题意后很简单的题。
首先我们用map键值对记录键盘中每个字符所在的位置,用数组同理,可以记录a~z每个字符的位置。然后遍历一遍所给的单词,从第二位开始,直接累加该单词的第ii-1位的字符在键盘中所在位置的距离差即可。记得取绝对值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<char,int> mp;
int main()
    int t;
    cin>>t;
    while(t--)
        mp.clear();
        string s;
        cin>>s;
        for(int i=0;i<s.size();i++)
            mp[s[i]]=i;
        
        string opp;
        cin>>opp;
        ll ans=0;
        for(int i=1;i<opp.size();i++)
            ans+=abs(mp[opp[i]]-mp[opp[i-1]]);
        
        cout<<ans<<endl;
    
    return 0;

E.小明打篮球

小明在第 n n n 局使用招式,必胜。其它局的胜率为 50%
而且,根据这句话的提示:
说明:获得胜利的条件是小明在 x x x 局比赛中赢下 ( x + 1 ) 2 \\frac(x+1)2 2(x+1) 局以上,例如3局2胜,5局3胜…
可以列出公式: ( x + 1 ) 2 = n \\frac(x+1)2=n 2(x+1)=n
解得: x = 2 ⋅ n − 1 x=2·n-1 x=2n1 即为最终答案。
解释:小明会在除第 n n n 局的共 x − 1 x-1 x1 局的偶数局中赢得一半的胜利。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
    int t;
    cin>>t;
    while(t--)
        ll n;
        cin>>n;
        cout<<(2*n-1)<<endl;
    
    return 0;

F.小明爱数学

本题也是一个十分简单的签到题,是我出题出到一半,突然觉得前面有点不符合预期难度,所以又加了一道简单题。还有点小私心,拿自己名字命了个名。
写过斐波那契数列的同学应该都能一眼出结果,给定首项和第二项然后去用公式模拟到第 n n n 项,因为 n n n 比较小用了一个数组。

#include<bits/stdc++.h>
using namespace std;
int f[105];
int main()
    int n,a,b;
    cin>>n>>a>>b;
    f[1]=a;
    f[2]=b;
    for(int i=3;i<=n;i++)
        f[i]=(f[i-1]+f[i-2])%8;
    
    cout<<f[n]<<endl;
    return 0;

G.小明与张三

有多少个格子可以通过命令走出去。
就是一道搜索类的小模拟题,本来是要剪枝的,但是因为oj里面c++和Java,Python都只能开同一个时间限制,所以考虑到可能会TLE,就没卡数据,我也不知道不剪枝写能不能过,反正我写题解的时候还没开始比赛。
写法就是以每一个点作为起点,去搜索,通过指令进行上下左右的移动,然后判断是否在循环(失败),或者已经走出边界(成功)。
判断是否在循环给两种方式,一是访问到了之前访问过的点,用vis[]数组提前记录访问过的点;二是深搜走的深度是不是超过了 n ⋅ m n·m nm 步,那就说明一定是在循环。
最后通过统计能走出的点的个数输出即可。
剪枝:当该点走到之前已经记录好能出去的点时,就不需要再向下搜索,可以直接返回true值,表示成功走出边界。

#include<bits/stdc++.h>
using namespace std;
char mp[1005][1005];
int vis[1005][1005];
int ris[1005][1005];
int n,m;
// W A S D
int dir[4][2]=
    -1,0,0,-1,1,0,0,1
;
map<char,int> mpp;
bool check(int x,int y)
    if(x<1||x>n||y<1||y>m) return true;
    else return false;

bool dfs(int x,int y)
    if(check(x,y))
        ris[x][y]=1;
        return true;
    
    int k=mpp[mp[x][y]];
    int xx=x+dir[k][0],yy=y+dir[k][1];
    if(ris[xx][yy]) return true;
    if(vis[xx][yy]) return false;
    vis[xx][yy]=1;
    if(dfs(xx,yy))
        ris[xx][yy]=1;
        return true;
    else
        return false;
    

int main()
    ios::sync_with_stdio(false);
    mpp['W']=0;
    mpp['A']=1;
    mpp['S']=2;
    mpp['D']=3;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>mp[i][j];
        
    
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            vis[i][j]=1;
            if(dfs(i,j))
                ans++;
            
            vis[i][j]=0;
        
    
    cout<<ans<<endl;
    return 0;

H.小明拿宝藏

改编自01背包模板。
加了一个条件,必须拿第一件物品。
只需要在最初时读入这件物品,减掉相应的背包容量,后续假装这件物品不存在即可。
01背包:
二维即可过题。
dp[i][j] 表示第 i 件物品,在背包容量还剩 j 的大小时,承放的最大价值。
第一维循环物品,第二维循环背包容量。
一维要倒叙第二重循环,因为这样背包容量<=j中的状态还是i-1的状态。

如果背包装得下当前的物体,在遍历过程中分别计算第i件物体放入和不放入背包的价值,取其中大的作为当前的最大价值。
如果背包装不下当前物体那么第i个物体只有不放入背包一种选择。

不放入背包时:第 i i i 次决策后的最大价值和第 i − 1 i-1 i1 次决策时候的价值是一样的(还是原来的那些物体,没多没少)。
放入背包时:第 i i i 次决策后的价值为 第 i − 1 i-1 i1 次决策时候的价值加上当前物体的价值v[j]。物体放入背包后会使背包容量变为 j j j ,即没放物体之前背包的容量为j - w[i]

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int dp[N];
int v[N],w[N];
int n,m;
int main()
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
    m-=v[1];
    for(int i=2;i<=n;i++)
        for(int j=m;j>=v[i];j--)
            dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
        
    
    cout<<dp[m]+w[1]<<endl;
    return 0;

I.小明的考试成绩

我又填了一道简单题。
好像前面又难了。
这道题就是考察排序的题目,就算冒泡也能通过。
只是用二维数组的方式给你,只需要把给定的所有数字存下,特别的记录一下小明所在位置的成绩,然后排序,排好序后降序找到小明的成绩所在的位置的下标,即为小明的成绩。

#include<bits/stdc++.h>
using namespace std;
vector<int> ve;
bool cmp(int x,int y)
    return x>y;

int main()
    int n,m;
    int x,y,k,w;
    cin>>n>>m;
    cin>>x>>y;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>k;
            ve.push_back(k);
            if(i==x&&j==y) w=k;
        
    
    sort(ve.begin(),ve.end(),cmp);
    for(int i=0;i<n*m;i++)
        if(ve[i]==w)
            cout<<i+1<<endl;
            break;
        
    
    return 0;

J.小明与鲜花

考察的容斥原理应用。
因为黑盒数据简单,多重背包也可

以上是关于桂林信息科技学院第一届程序设计大赛完整题解 C++的主要内容,如果未能解决你的问题,请参考以下文章

桂林信息科技学院第一届程序设计大赛完整题解 C++

北京大学信息工程学院雷凯副教授作为评委 参加中国深圳创新创业大赛第一届国际赛

第二届华中科技大学研究生人工智能创新大赛决赛顺利举行

第三届“扬海科技杯”数据库技能大赛成功举办!

信息工程学院第五届科技文化节之C语言编程大赛

广州城建 | 第三届“扬海科技杯”数据库技能大赛成功举办!