上海市青少年算法2021年7月月赛(丙组)

T1 布置会场
题目描述
激动人心的 2021YACS线下赛 下个月就要举办了!为了欢迎各位OI选手,主办方决定用百合花和郁金香两种花朵布置场地。
负责比赛组织的小爱老师了解到,花店的销售方式如下:
一束百合花的价格为a元
一束郁金香的价格为b元
半束百合花+半束郁金香的双拼花束价格为c元
小爱老师可以购买两份双拼花束后,将他重新组合成一束百合花+一束郁金香。已知布置会场需要用到x束百合花与y束郁金香,请问小爱老师购买花朵最少花费需多少元?
输入格式
输入共两行:
第一行:两个正整数表示需要的花束数量x,y
第一行:三个正整数表示花束费用a,b,c
输出格式
输出共一行,一个正整数,表示小爱老师购买花朵最少花费需多少元。
数据范围
对于30%的数据:1≤x,y≤100,1≤a,b,c≤10
对于100%的数据:1≤x,y≤1000,1≤a,b,c≤500
样例数据
输入:
8 6
8 10 8
输出:
112
说明:
先购买12束双拼花朵,花费12*8=96元,
再购买2束百合花,花费2*8=16元,
总计112元。
输入:
8 6
8 10 12
输出:
124
说明:
直接购买8束百合+6束郁金香,共计8*8+6*10=124元。

/*分三种情况:
1.两个双拼花束的价格少于一个花束a加一个花束b的价格;
2.两个双拼花束的价格少于一个花束a的价格
3.两个双拼花束的价格少于一个花束b的价格
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
	int x,y,a,b,c,ans=0;
	cin>>x>>y>>a>>b>>c;
	c*=2;//两个半束 合成1束
	int t=min(x,y);
	if(c<(a+b)){
		ans+=c*t;x-=t,y-=t;
	}
	if(a>c)a=c;
	if(b>c)b=c;
	ans+=a*x+y*b;
	cout<<ans<<endl;
    return 0;
}

T2 选科组合
题目描述
2017年起,上海高考正式从3+1模式,改变为3+3模式,即 语文、数学、外语 三门科目必考,物理、化学、生物、历史、地理、政治 这6门科目中任意选择三门考试,不再区分文理科。即将面临选科的小爱收到了最近一次考试的成绩,并以此为依据进行选科。
已知小爱 物理、化学、生物、历史、地理、政治 成绩分别为a分,b分,c分,d分,e分,f分。请问按此成绩,小爱选择高考三门科目所能得到的最高分为多少分?
输入格式
输入共一行,6个正整数,分别表示小爱的6科成绩
输出格式
输出共一行,输出小爱选择3门考试科目所能得到的最高分分值。
数据范围
0≤a,b,c,d,e,f≤100
样例数据
输入:
90 88 85 93 75 87
输出:
271
说明:
选择物理、化学、历史三门课,所得分数最高,分值为90+88+93=271分。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int cmp_(const int a,const int b){
	return a>b;
}
int main()
{
	int a[7];
	for(int i=1;i<=6;i++) cin>>a[i-1];
	sort(a,a+6,cmp_);
	cout<<a[0]+a[1]+a[2]<<endl;
    return 0;
}

T3 进制回文
题目描述
给定一个十进制数字 x,若它满足在任意一个 B 进制(2≤B≤16)下是一个回文数,我们就称这个数字为进制回文数。
例如:当 x=5x=5 时,其对应二进制数字 (101)2
​是一个回文数,我们称十进制数字 55 是一个进制回文数。
现在给定一个十进制正整数 xx,请问 xx 是否是进制回文数。若是,则输出 Yes,并从小到大输出它在 2 到 16 进制中,哪些进制下是回文数,若不是,则输出 No。
输入格式
输入共一行,一个正整数:x。
输出格式
输出第一行:该数字是否是进制回文数,
输出第二行:输出该数字在哪些进制下(只考虑2~16进制)是回文数,以空格隔开。
数据范围
对于100%的数据:1≤x≤10^9,2≤B≤16
样例数据
输入:
5
输出:
Yes
2 4 6 7 8 9 10 11 12 13 14 15 16
说明:
十进制数字5在2进制、4进制、6进制一直到16进制下,都是回文数。

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int n;
bool jinzh(int n,int i){
	string a,b;
	while(n>0){
		if(n%i>9) a+=(char)(n%i-10+'a');
		else a+=(char)(n%i+'0');
		n/=i;
	}
	b=a;reverse(a.begin(),a.end());
	if(a==b) return true;
	else return false;
}
int main(){
	cin>>n;
	bool flag=false;
	for(int i=2;i<=16;i++) {
		if(jinzh(n,i)){
			if(!flag) {flag=true;cout<<"Yes"<<endl;}
			cout<<i<<" ";
		}
	}
	if(!flag) cout<<"No"<<endl;
	return 0;
}

T4 比赛组卷
题目描述
小爱老师正在准备计算机知识竞赛的考试试题,认真负责的她精心挑选了 k 道试题(编号1~k)组成了题库,并由系统随机抽选其中 n 题作为考试试卷。
系统在组卷时自动组成了A卷和B卷,其中A卷n道题的编号为a1,a2,…,an,其中BB卷nn道题的编号为b1,b2,…,bn。
请你帮小爱老师计算一下,有多少道试题同时出现在A,B卷中,并按从小到大的顺序给出重复试题的编号。
输入格式
输入共三行:
第一行,两个正整数表示n,k
第二行,n个正整数表示a1,a2,…,an
第三行,nn个正整数表示b1,b2,…,bn
输出格式
输出第一行:重复试题的数量
输出第二行:按从小到大顺序输出重复试题的编号
(若第一行重复试题的数量为0,则不用输出第二行的信息)
数据范围
对于30%的数据,1≤k≤10
对于70%的数据,1≤k≤10^4
对于100%的数据,1≤k≤10^5
 1≤n≤k,1≤a1,a2,…,an≤k,1≤b1,b2,…,bn≤k
样例数据
输入:
5 10
1 2 3 4 5
10 9 8 7 6
输出:
0
说明:
A,B卷没有出现重复试题
输入:
5 10
6 4 1 8 10
5 1 7 4 6
输出:
3
1 4 6
说明:
A,B卷中均出现了编号为1,编号为4,编号为6的题目,其余题目没有重复

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int n,k,a[100005],f[100005];//注意数据量
int main(){
	cin>>n>>k;
	int t,ans=0;
	for(int i=0;i<n;i++) {
		cin>>t;f[t]++;
	}
	for(int i=0;i<n;i++) cin>>a[i];
	sort(a,a+n);
	for(int i=0;i<n;i++){
		if(f[a[i]]>0) {ans++;f[a[i]]++;}
	}
	cout<<ans<<endl;
	if(ans==0) return 0;
	for(int i=0;i<n;i++)
		if(f[a[i]]>1) cout<<a[i]<<" ";
	return 0;
}

T5 消消乐(一)
题目描述
消消乐游戏可以看成一个n×m的方格图,每个方格上放置着可以消除的水果或是不可移动与消除的障碍物。玩家可以通过交换相邻的水果,使同一水果组成超过连续3个,便可将其消除。除此之外,还有一种道具叫做水果炸弹,在水果或空白格放置水果炸弹,便可从水果炸弹位置开始,同时向上下左右四个方向炸出,并消除沿途的水果,直至碰到障碍物为止。
例如下图所示:图中'#'部分表示为障碍物,若在五角星处放置水果炸弹,其消除的水果范围在图中用红色方块表示,则在该位置放置水果炸弹可以消除的水果数量为14个。

 给定游戏当前进行在一个n×m方格图上,每个格子用'.'表示水果,'#'表示障碍物,你拿到一个水果炸弹,请你计算如何放置水果炸弹,能使消除的水果数量最多,最多为多少个?
输入格式
输入第一行,两个正整数n,m
接下来n行:每行m个字符,表示游戏方格的状态。
输出格式
输出一个正整数,表示最多能消除的水果数量
数据范围
对于30%的数据,1≤n,m≤10
对于60%的数据,1≤n,m≤100
对于100%的数据,1≤n,m≤1000
样例数据
输入:
4 4
##.#
...#
#...
####
输出:
5
说明:
将水果炸弹放置在(2,3)位置,此时最多能够消除5个水果

//暴力 未AC
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int n,m;
char c[1005][1005];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) cin>>c[i][j];
	int maxn=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			if(c[i][j]=='.'){
				int t=0;
				int x=i-1,y=j+1;
				while(c[x][j]=='.'&&x>=1){x--;t++;}
				while(c[i][y]=='.'&&y<=m){y++;t++;}
				x=i+1,y=j-1;
				while(c[x][j]=='.'&&x<=n){x++;t++;}
				while(c[i][y]=='.'&&y>=1){y--;t++;}
				t++;
				maxn=max(maxn,t);
			}
		}
	cout<<maxn<<endl;
	return 0;
}
//前缀和AC
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int n,m;
char c[1005][1005];
struct T{
	int x,y;
}s1[1005][1005],s2[1005][1005];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			cin>>c[i][j];
			if(c[i][j]=='.'){
				s1[i][j].x=s1[i][j-1].x+1;//左->右 前缀和
				s1[i][j].y=s1[i-1][j].y+1;//上->下 前缀和	
			}
		}
	for(int i=n;i>=1;i--)
		for(int j=m;j>=1;j--){
			if(c[i][j]=='.'){
				s2[i][j].x=s2[i][j+1].x+1;//右->左 前缀和
				s2[i][j].y=s2[i+1][j].y+1;//下->上 前缀和	
			}
		}
	int maxn=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			int t=s1[i][j].x+s1[i][j].y+s2[i][j].x+s2[i][j].y-3;
			maxn=max(maxn,t);
		}
	cout<<maxn<<endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/lybc2019/article/details/121361844