桂林信息科技学院第一届程序设计大赛完整题解 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 的末位为偶数时,结果为0else if
当 n n n 的首位是偶数时,结果为1else 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
每个字符的位置。然后遍历一遍所给的单词,从第二位开始,直接累加该单词的第i
与i-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=2⋅n−1 即为最终答案。
解释:小明会在除第
n
n
n 局的共
x
−
1
x-1
x−1 局的偶数局中赢得一半的胜利。
#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
n⋅m 步,那就说明一定是在循环。
最后通过统计能走出的点的个数输出即可。
剪枝:当该点走到之前已经记录好能出去的点时,就不需要再向下搜索,可以直接返回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
i−1 次决策时候的价值是一样的(还是原来的那些物体,没多没少)。
放入背包时:第
i
i
i 次决策后的价值为 第
i
−
1
i-1
i−1 次决策时候的价值加上当前物体的价值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++的主要内容,如果未能解决你的问题,请参考以下文章