郑州大学“战役杯”第二次比赛题解

1 公司的Logo

为了感谢河南省八六三软件有限公司对战疫杯ACM在线程序设计竞赛的大力支持,小Y决定为公司制作个logo。

logo通常要用在各种不同的场景,因此logo的尺寸必须是可变的。现给你原始的logo,以及其改变尺寸的例子,你能寻找规律并输出任意缩放后的logo图案吗?

原始logo:

### ### ###
# # #     #
### ### ###
# # # #   #
### ### ###

将其放大一倍的示例:

#### #### ####
#  # #       #
#  # #       #
#### #### ####
#  # #  #    #
#  # #  #    #
#### #### ####

其放大两倍的示例是

##### ##### #####
#   # #         #
#   # #         #
#   # #         #
##### ##### #####
#   # #   #     #
#   # #   #     #
#   # #   #     #
##### ##### #####

输入格式:

输入一个整数n(0≤n≤10),表示放大的倍数。特别的,n等于0时输出原字符画。

输出格式:

输出对应倍数的字符画。

输入样例:

1

输出样例:

#### #### ####
#  # #       #
#  # #       #
#### #### ####
#  # #  #    #
#  # #  #    #
#### #### ####

源代码

题解思路:

我们可以发现对于第0、5+2*n-1和第(5+2*n-1)/2行的团都是由三部分相同的#组成

且从列方面看在第3+n列和第(3+n)*2+1列都有一个空格出现

这三行除了这两列的空格其余均为#来填充

扫描二维码关注公众号,回复: 14215968 查看本文章

然后我们从其余行开始看

很清晰上半部分在第0、11+3*n-1、3+n-1、3+n-1+2列只出现了#

下半部分在第0、11+3*n-1、3+n-1、3+n-1+2、3+n-1+2+3+n-1列出现了#

所以我们可以对图进行上下部分处理

另外图的放缩的话对于行是按照5+n*2的规律放缩

对于列是按照11+3*n的规律进行放缩

暴力模拟

#include <iostream>
using namespace std;
const int N = 1000+10;//为图开辟空间
char g[N][N];//创建二维字符数组进行图的存储
int main()
{
	int n;
	cin>>n;
	int space1=3+n;//首个空格所在列数
	int space2=(3+n)*2+1;//第二个空格所在列数
	for(int i = 0;i <5+n*2;i ++ )
	{
		for(int j = 0;j < 11+3*n;j ++ )
		{
            //对于三行特殊的图案进行处理
			if(i==0||i==5+n*2-1||i==(5+2*n-1)/2)
			{
				if(j==space1||j==space2)
				{
					g[i][j]=' ';
				}
				else g[i][j]='#';
			}
			else
			{
                //对于图的上半部分处理
				if(i>=0&&i<=(5+2*n-1)/2)
				{
					if(j==0||j==11+3*n-1||j==3+n-1||j==3+n-1+2)
					{
						g[i][j]='#';
					}
					else g[i][j]=' ';
				}
				else
				{
                    //对于图的下半部分处理
					if(j==0||j==11+3*n-1||j==3+n-1||j==3+n-1+2||j==3+n-1+2+3+n-1)
					{
						g[i][j]='#';
					}
					else g[i][j]=' ';
				}
			}
		}
	}
    //对图进行逐行输出
	for(int i = 0;i <5+n*2;i ++ )
	{
		puts(g[i]);
	}
	return 0;
}

 2 解封日期

小明所在的城市发生了疫情,实行静态化管理,小明也被关在家里,不能去上学了。

根据当地政策,连续N天没有新增病例,就可以解封。小明知道过去M(M≤N)天的每天的新增病例数,他想知道理想情况下最早什么时候可以解封。

输入格式:

第一行一个日期,格式为YYYY/MM/DD。

第二行两个整数N和M,0<M≤N≤30。

之后M行,每行一个整数0≤Xi​≤100,0≤i<M,表示从今天开始,往过去数第i天的新增病例数(包括今天)。

输出格式:

一行,一个日期,格式为YYYY/MM/DD,请不要有多余的空格。

输入样例:

2004/10/28
4 2
1
0

输出样例:

2004/11/01

源代码

首先我们创建了两个一维数组分别用来存储闰年月份天数和平年月份天数

动态数对对于每次输入的数据进行存储

从动态数对的头开始遍历,查找出现病例的那天,如果没有则将偏移量加一

最小天数加上偏移量即为所需要多少天才能解封

注意数据M>=N(避免考虑复杂),这里我的偏移量为负数

因此n加上偏移量一定是大于等于0的

所以最短解封时间一定在今天以及今天之后

所以我们可以放心的使用while对n--判断从而往后累加天数

注意在累加之前我们要先对年份进行类型判断

累加时注意月份的进位和年份的进位

#include <iostream>
#include <vector>
using namespace std;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//平年月份天数数组
int b[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年月份天数数组
typedef pair<int,int> PII;
vector<PII> A;//动态数对
int main()
{
    //格式化输入获取当前年月日
	int year,month,day;
	scanf("%4d/%2d/%2d",&year,&month,&day);
	int n,m;
	cin>>n>>m;
	for(int i = 1;i <= m;i ++ )
	{
        //注意key的值即为偏移量的值我们直接按照下标作为偏移量存储
		int key=i-1;
		int num;
		cin>>num;
		A.push_back({key,num});//存进去
	}
	int delta=-m;//默认动态数对中的数据是没有病例出现的,此时偏移量为m
	for(int i = 0;i < A.size();i ++ )
	{
        //如果查找到了病例出现的那天
		if(A[i].second!=0)
		{
			delta=-A[i].first;//更新偏移量的值
			break;//直接跳出循环
		}
	}
	n=n+delta;//n与偏移量进行处理
	if((year%4==0&&year%100!=0)||year%400==0)//闰年
	{
		while(n--)//累加天数
		{
			day++;
			if(day>b[month])//注意月份进位
			{
				month++;
				day=1;
			}
			if(month>12)//注意年份进位
			{
				year++;
				month=1;
			}
		}
	}
	else//平年
	{
		while(n--)//累加天数
			{
				day++;
				if(day>a[month])//注意月份进位
				{
					month++;
					day=1;
				}
				if(month>12)//注意年份进位
				{
					year++;
					month=1;
				}
			}
	}
    //输出最早解封的日期
	printf("%4d/%02d/%02d",year,month,day);
	return 0;
} 

 3 语音设备是否正常?

因疫情防控改为线上授课后,有些同学开始沉迷游戏。你的寝室有个室友最近喜欢了一款游戏:Hxxxxx Dxxxx。该游戏能够正常进行的重要前提就是所有玩家的语音输入设备都是正常的,即每个玩家需要通过麦克风与其他玩家交流。该游戏有8种角色,每人进入游戏房间时需要不重复地选择一种角色,游戏房间满8人后,房主可以正常开启本局游戏。玩家进入房间后,通常需要通过语音与其他玩家交流,以证明自己的麦克风设备是正常的。作为房主,需要时刻了解当前进入房间的其他玩家是否通过麦克风交流过,进而决定是否开启本局游戏,或者踢出没有说过话的玩家。你的室友作为房主,你能通过程序设计帮助他这个忙吗?另外,房主保证自己的设备是没问题的。

说明:该游戏中的8中角色分别为船长(Captain), 牧师(Priest),厨师(Cook),医生(Doctor),工程师(Engineer),猎人(Hunter),枪手(Gunner), 导航官(Navigator)。

后记:帮助完房主设计完这个程序后,你愈发觉得作为一个计算机专业的学生,应该去尝试编程写一个游戏赚别人钱,而不是浪费时间还花钱玩游戏。从此你一发而不可收拾,游戏编程界的一颗新星冉冉升起!

输入格式:

第一行一个字符串,表示房主建立房间所选择的角色;
第二行一个正整数N,0<N≤1000,表示语音的条数;
以下N行字符串,每一行都是形如:

角色: XXX XXX XXX XX

表示哪个角色通过语音说了什么话。中间是英文冒号,每行字符串长度不超过200。

输出格式:

如果所有玩家设备均正常,输出"Ready"(不包括引号);否则输出没有语音交流过的玩家角色名,每行一个(按照角色单词的字典序从小到大依次输出)。

输入样例1:

Captain
10
Hunter:Hi.
Navigator:Hello, everyone
Doctor:here is the doctor.
Priest:voice test
Hunter:is my device ready?
Captain: yes
Cook:chu shi you mai
Gunner:of course
Engineer: i'm ready
Gunner: go go

输出样例1:

Ready

输入样例2:

Priest
7
Hunter:Hi.
Engineer: i'm ready
Navigator:Hello, everyone
Doctor:here is the doctor.
Hunter: is my device ready?
Gunner:of course
Gunner: how about the cook?

输出样例2:

Captain
Cook

 源代码

map暴力方法

使用find函数查找

将未出现的职业推入动态数组当中并进行字典序排序 

#include <iostream>
#include <map>//容器暴力
#include <string.h>//find函数
#include <vector>//动态数组
#include <algorithm>//sort排序
using namespace std;
map<string,string> P;//定义map容器
vector<string> A;//定义动态数组
int main()
{
	string s;
	cin>>s;
    //首先对于房主的职业存储
	P[s]="Ready";
	int n;
	cin>>n;
	while(n--)
	{
        //依次对于八个职业进行查,查找到了则在容器中改其值为Ready
		string str;
		getline(cin,str);
		if(str.find("Captain")!=-1)
		{
			P["Captain"]="Ready";
		}
		else if(str.find("Hunter")!=-1)
		{
			P["Hunter"]="Ready";
		}
		else if(str.find("Priest")!=-1)
		{
			P["Priest"]="Ready";
		}
		else if(str.find("Cook")!=-1)
		{
			P["Cook"]="Ready";
		}
		else if(str.find("Doctor")!=-1)
		{
			P["Doctor"]="Ready";
		}
		else if(str.find("Engineer")!=-1)
		{
			P["Engineer"]="Ready";
		}
		else if(str.find("Gunner")!=-1)
		{
			P["Gunner"]="Ready";
		}
		else if(str.find("Navigator")!=-1)
		{
			P["Navigator"]="Ready";
		}
	}
    //查找八个职业哪儿个职业未出现,将未出现的职业压入动态数组当中
	if(P["Captain"]!="Ready")A.push_back("Captain");
	if(P["Hunter"]!="Ready")A.push_back("Hunter");
	if(P["Priest"]!="Ready")A.push_back("Priest");
	if(P["Cook"]!="Ready")A.push_back("Cook");
	if(P["Doctor"]!="Ready")A.push_back("Doctor");
	if(P["Engineer"]!="Ready")A.push_back("Engineer");
	if(P["Gunner"]!="Ready")A.push_back("Gunner");
	if(P["Navigator"]!="Ready")A.push_back("Navigator");
    //当动态数组中所存储元素为0即所有职业都出现时
	if(A.size()==0)cout<<"Ready";//输出准备好了
	else//当有职业未出现时
	{
		sort(A.begin(),A.end());//首先对于职业进行字典序排序
		for(int i = 0;i < A.size();i ++ )cout<<A[i]<<endl;//再依次输出未出现的职业
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/couchpotatoshy/article/details/124697074