湖南中医药大学信息科学与工程学院第四届大学生程序设计竞赛——正式赛题解
Posted a碟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了湖南中医药大学信息科学与工程学院第四届大学生程序设计竞赛——正式赛题解相关的知识,希望对你有一定的参考价值。
目录
- 问题A:X星人的统计
- 问题B:X星人的报数
- 问题C:X星人的迷宫
- 问题D:X星人的高考
- 问题E:X星人的匹配
- 问题F:X星人的成绩
- 问题G:X星人的变换
- 问题H:X星人的游戏
- 问题I:X星人的宝石
- 问题J:X星人的车牌
- 问题K:X星人的括号
- 问题L:X星人的翻译
问题A:X星人的统计
题目描述
一年一度的X星人口普查又开始了,其中有一项是统计各民族X星人的数量。X星人分属四个不同的民族,四个民族分别用A、B、C和D表示。
现在给出N个X星人的民族信息,请统计各民族X星人的总数。
输入
单组输入。
第1行输入统计的总人数N,N<=10^6。
第2行输入N个X星人的民族信息,四个民族分别用A、B、C和D表示,两两之间用英文空格隔开。
输出
请按照A、B、C、D的顺序分别输出每一个民族的总人数,两两之间用英文空格隔开。
样例输入
10
A C B D A C B D D A
样例输出
3 2 2 3
分析
签到题,直接按照题意模拟即可
代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e6+5;
int num[5];
int main()
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
getchar();
char x;scanf("%c",&x);
num[x-'A']++;
for(int i=0;i<4;i++)
if(i!=3)printf("%d ",num[i]);
else printf("%d\\n",num[3]);
return 0;
问题B:X星人的报数
题目描述
N个X星人站成一排,他们发明了一种奇怪的报数方式。
从第1个人开始报数,第1个人报数为1,第2个人报数为2,接下来奇数位置的人报数为前一个人报数加1,偶数位置的人报数为前一个人的两倍。
请问第N个人的报数是多少?
输入
输入一个正整数N(N<=40)。
输出
输出第N个人的报数。
样例输入
4
样例输出
6
题解
签到题,也是按照题目意思简单模拟即可。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=45;
int a[N];
int main()
int n;scanf("%d",&n);
a[1]=1,a[2]=2;
for(int i=3;i<=n;i++)
if(i%2)a[i]=a[i-1]+1;
else a[i]=2*a[i-1];
printf("%d\\n",a[n]);
return 0;
问题C:X星人的迷宫
题目描述
X星人进入了一个树形迷宫,该迷宫由一个N层的满二叉树组成。迷宫的每一个节点都有一个计分权重,只有找到那条从根节点开始到叶子结点的计分权重和最大的路径,X星人才能够顺利走出迷宫。
现在给出该树形迷宫每一个节点的权重值,你能否编写一个程序计算出权重和最大的路径所对应的总权重。
输入
单组输入
第1行输入一个正整数N,表示二叉树的节点层数。(N<=20)
第2行输入2^N-1个正整数,分别表示迷宫中每一个节点的权重,两两之间用英文空格隔开。第1个数字表示根节点的权重,接下来两个数字表示根节点左、右孩子的权重,再接下来四个数字表示第3层的四个节点的权重,…,以此类推。每个节点的权重均不超过1000。
输出
输出从根节点出发到叶子节点权重和最大的路径所对应的权重。
样例输入
3
10 20 30 100 20 50 40
样例输出
130
题解
中等题,直接用DFS或者BFS搜索,搜索到根节点时,维护一个最大的权重即可。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=1500000+5;
int a[N];
int n,ans=0;
void dfs(int x,int sum)
if(x>n)return ;
sum+=a[x];
ans=max(ans,sum);
dfs(x*2,sum);
dfs(x*2+1,sum);
int main()
scanf("%d",&n);
n=pow(2,n)-1;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
dfs(1,0);
printf("%d\\n",ans);
return 0;
问题D:X星人的高考
题目描述
一年一度的X星高考如期举行。今年X星新高考一卷的数学真的很难,据说把很多考生都考哭了。
今年数学考试的多选题仍然是4道题,每题5分,共20分。在每小题给出的4个选项中,有多项符合题目要求,全对得5分,选对但不全得2.5分,有选错的得0分。每道题均包含A、B、C和D四个选项。
现在给出某X星考生的多选题答案和正确答案,请编写一个程序计算该X星考生最终多选题的得分
输入
单组输入。
每组输入两行,第1行包含该X星人四道多选题的答案,两两之间用空格隔开;第2行包含四道多选题的正确答案,两两之间用空格隔开(答案不一定按照字典序排列)。
输出
输出该X星考生最终多选题的得分(答案保留一位小数)。
样例输入
A BC AC ABC
AB BC AD AB
样例输出
7.5
题解
简单题,可以直接在正确答案中依次判断是否存在X星考生选择的答案,若全部完全匹配,则全对得5分;若选对但不全对得2.5分;一旦有选错的得0分。
需要注意,ABCD是包含AD的,一开始有的同学直接判断在ABCD中使用find函数,查是否能find到AD,这是显然不对的。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
string a[5],b[5];
int main()
for(int i=1;i<=4;i++)cin>>a[i];
for(int j=1;j<=4;j++)cin>>b[j];
double ans=0;
for(int i=1;i<=4;i++)
string s=a[i],t=b[i];
int num=0,flag=1;
for(int i=0;i<s.size();i++)
if(t.find(s[i])<t.size())num++;
else flag=0;
if(flag)
if(num==t.size())ans+=5;
else ans+=2.5;
printf("%.1f\\n",ans);
return 0;
问题E:X星人的匹配
题目描述
X星人有一个只包含数字0和1的目标串a和一个匹配串b ,匹配串除了0和1还有两种特殊匹配符,第一种是’?‘可以匹配任何一个字符,另外一种是’*'可以匹配任意字符串(包含空字符串),现在需要你判断目标串和匹配串能不能完全匹配(对于两个串都不能有未匹配字符)。
输入
单组输入,第一行输入目标串a,第二行输入匹配串b。输入保证两个字符串长度均<=1e3。
输出
完全匹配输出true,否则输出false。
样例输入
00
*
样例输出
true
题解 以上是关于湖南中医药大学信息科学与工程学院第四届大学生程序设计竞赛——正式赛题解的主要内容,如果未能解决你的问题,请参考以下文章 湖南中医药大学信息科学与工程学院第四届大学生程序设计竞赛——正式赛题解
困难题,动态规划,
d
p
(
i
,
j
)
dp(i,j)
dp(i,j) 代表考虑
a
a
a中以
i
i
i为结尾的子串和
b
b
b中的
j
j
j为结尾的子串是否匹配。即最终我们要求的结果为
d
p
[
n
]
[
m
]
dp[n][m]
dp[n][m](
n
n
n为
a
a
a串的长度,
m
m
m为
b
b
b串的长度)。
状态转移:也就是我们要考虑
d
p
(
i
,
j
)
dp(i,j)
dp(i,j)如何求得,前面说到了
b
b
b有三种字符,所以这里的状态转移也要分三种情况讨论:
b
[
j
]
b[j]
b[j]为普通字符:匹配的条件是前面的字符匹配,同时
a
a
a中的第
i
i
i个字符和
b
b
b中的第
j
j
j位相同。 即
d
p
(
i
,
j
)
=
d
p
(
i
−
1
,
j
−
1
)
&
&
a
[
i
]
=
=
b
[
j
]
dp(i,j) = dp(i - 1, j - 1) \\&\\& a[i] == b[j]
dp(i,j)=dp(i−1,j−1)&&a[i]==b[j] 。
b
[
j
]
b[j]
b[j] 为
′
?
′
'?'
′?′:匹配的条件是前面的字符匹配,
a
a
a中的第
i
i
i个字符可以是任意字符。即
d
p
(
i
,
j
)
=
d
p
(
i
−
1
,
j
−
1
)
&
&
b
[
j
]
=
=
′
?
′
dp(i,j)=dp(i-1,j-1)\\&\\&b[j]=='?'
dp(i,j)=dp(i−1,j−1)&&b[j]==′?′。
b
[
j
]
b[j]
b[j]为
′
∗
′
'*'
′∗′:可匹配任意长度的字符,可以匹配
0
0
0个字符、匹配
1
1
1个字符、匹配
2
2
2个字符…
当匹配为
0
0
0个:
d
p
(
i
,
j
)
=
d
p
(
i
,
j
−
1
)
dp(i,j)=dp(i,j-1)
dp(i,j)=dp(i,j−1)
当匹配为
1
1
1个:
d
p
(
i
,
j
)
=
d
p
(
i
−
1
,
j
−
1
)
dp(i,j)=dp(i-1,j-1)
dp(i,j)=dp(i−1,j−1)
当匹配为
2
2
2个:
d
p
(
i
,
j
)
=
d
p
(
i
−
2
,
j
−
1
)
dp(i,j)=dp(i-2,j-1)
dp(i,j)=dp(i−2,j−1)
…
当匹配为
k
k
k个:
d
p
(
i
,
j
)
=
d
p
(
i
−
k
,
j
−
1
)
dp(i,j)=dp(i-k,j-1)
dp(i,j)=dp(i−k,j−1)
因此对于
b
[
j
]
=
′
∗
′
b[j]='*'
b[j]=′∗′的情况,想要
d
p
(
i
,
j
)
=
t
r
u
e
dp(i,j)=true
dp(i,j)=true,只需要其中一种情况为$true $即可。也就是状态之间是「或」的关系:
d
p
[
i
]
[
j
]
=
d
p
[
i
]
[
j
−
1
]
∣
∣
d
p
[
i
−
1
]
[
j
−
1
]
∣
∣
.
.
.
∣
∣
d
p
[
i
−
k
]
[
j
−
1
]
(