2020蓝桥杯 省模拟赛(大学本科组)题解

唔,今天水了个蓝桥的省模拟赛,写完没事干写个题解,欢迎各位大神前来指导哈!
题目顺序可能有偏差,凑乎看看,哈哈。

A题

2020蓝桥杯 省模拟赛(大学本科组)题解_第1张图片
签到题,呃签到也不算的大水题吧
1MB=1024KB=1024B
12.5 ×1024×1024=***13107200***
答案:13107200

B题

2020蓝桥杯 省模拟赛(大学本科组)题解_第2张图片
这题手算也还是快的,笑哭(其实还是不会排列组合)
1.() () () ()
2.() () (())
3.() (()) ()
4.(()) () ()
5.((())) ()
6.() ((()))
7.() () ()
8.() (()())
9.(() () ()
10.((())))
11.((()) ()
12.(() (())
13,(()) (())
14.((() ()))

诺,答案就出来**14**种

答案:14

C题

2020蓝桥杯 省模拟赛(大学本科组)题解_第3张图片
这也是很简单的排列组合,不过有个坑点是其中有两个相同单词a,我也是不幸掉坑,多亏小伙伴拉我一把,啊哈哈。

基本排列组合:7! / 2 = 2520

答案:2520

D题

2020蓝桥杯 省模拟赛(大学本科组)题解_第4张图片
这道题,比A题还水啊,基础知识,直接**2018**

E题

2020蓝桥杯 省模拟赛(大学本科组)题解_第5张图片
2020蓝桥杯 省模拟赛(大学本科组)题解_第6张图片
哈!终于,签到题出现
暴力循环+判断 perfect!!!

//author:wys
#include
#define ll long long
using namespace std;
int a,b,c;
int n,cnt;
int main() {
	cin>>n;
	for(int i=1;i<=3;i++)
	{
		cin>>a>>b>>c;	
	}
	for(int i=1;i<=n;i++)
	{
		if(i%a!=0&&i%b!=0&&i%c!=0)
		cnt++;
	}
	cout<<cnt;
	return 0;
}

F题

2020蓝桥杯 省模拟赛(大学本科组)题解_第7张图片
最爱的大水题啊不必多说了吧,直接贴代码吧

//author:wys
#include
#define ll long long
using namespace std;
char a[105];
int cnt;
int main() {
	cin>>a;
	int len=strlen(a);
	for(int i=0;i<len;i++)
	{
		if(a[i]>='a'&&a[i]<='z')
		{
			if(a[i]<'x')
			a[i]=a[i]+3;
			else
			a[i]=a[i]-'z'+'a'+2;
			cout<<a[i];
		}
	}
	return 0;
}

这个代码写的好渣,实在是当时不想动脑子了哎

G题

2020蓝桥杯 省模拟赛(大学本科组)题解_第8张图片
这道题的话,本蒟蒻第一眼看上去是dfs,又看眼数据,好像可行,就直接不客气地动手了,汗颜
思路:直接dfs按一条线走到底,而且中途能不拐弯就不拐弯,优先顺序“右下左上”,遍历一遍,途中给坐标记录编号就好。

//author:wys
#include
#define ll long long
using namespace std;
int n,m;
int a,b;
int yy[4]={1,0,-1,0};  //拐弯优先顺序:右下左上
int xx[4]={0,1,0,-1};
int vis[1005][1005];    //记录坐标编号
void dfs(int x,int y,int num,int k)  //k是记录上次行走的方向
{
	vis[x][y]=num;        //编号
	int newx=x+xx[k];
	int newy=y+yy[k];
	if(newy>0&&newx>0&&vis[newx][newy]==0&&newx<=n&&newy<=m)
	{
		dfs(newx,newy,num+1,k);   //如果可以直行就不要拐弯喽
	}
	else
	for(int i=0;i<4;i++)       //不能直行,需要拐弯了
	{
		newx=x+xx[i];
		newy=y+yy[i];
		if(newy>0&&newx>0&&vis[newx][newy]==0&&newx<=n&&newy<=m)
		{
			dfs(newx,newy,num+1,i);
		}
	}
	return ;
}
int main() {
	cin>>n>>m;
	cin>>a>>b;
	dfs(1,1,1,0);
/*	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cout<                   //打印螺旋矩阵图
	cout<<vis[a][b];
	return 0;
}

H题

2020蓝桥杯 省模拟赛(大学本科组)题解_第9张图片
2020蓝桥杯 省模拟赛(大学本科组)题解_第10张图片
这道题可给我打击的不轻,第一眼看上去。。嗯,还不错,绝对dp题
but…本蒟蒻不会啊,虽然看上去很简单,可怜巴巴
于是,怎么办,算了记忆化搜索吧,虽然不熟,但还是能勉强充充数


```cpp
//author:wys
#include
#define ll long long
using namespace std;
int m,n;
ll dp[1005][1005];
int dfs(int a,int c)     //意思是第c个数选a
{
	if(dp[a][c]!=-1)   //记忆化
	return dp[a][c];
	if(c==m)
	{
		dp[a][c]=1;
		return 1;
	}
		dp[a][c]=0;
		if(c&1)
		{
			for(int j=a+1;j<=n;j++)
			{
				dp[a][c]+=dfs(j,c+1); //如果c为奇数,那么下层选择比a大的数
				dp[a][c]%=10000;
			}
		}
		else
		{
			for(int j=a-1;j>=1;j--)
			{
				dp[a][c]+=dfs(j,c+1);//如果c为偶数,下层选比a小的数
				dp[a][c]%=10000;
			}
		}
	return dp[a][c]%10000;
	
}
int main() {
	cin>>m>>n;
	for(int i=1;i<=1003;i++)
	{
		for(int j=1;j<=1003;j++)
		{
			dp[i][j]=-1;
		}
	}
	ll f=0;
	for(int i=1;i<=n;i++)
	{
		f+=dfs(i,1);
		f%=10000;
	}
	cout<<f;
	return 0;
}

可惜可惜,蒟蒻暂时不会dp,记忆化搜索也不熟,只能c掉80%的数据,太弱了

I题

2020蓝桥杯 省模拟赛(大学本科组)题解_第11张图片
``2020蓝桥杯 省模拟赛(大学本科组)题解_第12张图片
这道题,也是很明显的最小生成树的模板题,so, Prim闪亮登场

//author:wys
#include
#define ll long long
using namespace std;
struct node{
	int x,y,h;
}a[1005];
double d[1005];    //顶点与集合的最短距离
int vis[1005];    //标记是否访问
double g[1005][1005]={0};
int n;
int main() {
	
	cin>>n;
	for(int i=0;i<n;i++){		
		cin>>a[i].x>>a[i].y>>a[i].h;
	}
	for(int i=0;i<n;i++){	
		for(int j=0;j<n;j++){		
			double t=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
			g[i][j]=sqrt(t)+(a[i].h-a[j].h)*(a[i].h-a[j].h);
			g[j][i]=sqrt(t)+(a[i].h-a[j].h)*(a[i].h-a[j].h);
		}
	}
	fill(d,d+1005,100000000);
	d[0]=0;
	double ans=0;
	for(int i=0;i<n;i++)
	{
		int u=-1,minn=100000000;
		for(int j=0;j<n;j++)
		{
			if(vis[j]==0&&d[j]<minn)
			{
				u=j;
				minn=d[j];
			}
		}
		vis[u]=1;
		ans+=d[u];
		for(int v=0;v<n;v++)
		{
			if(vis[v]==0&&g[u][v]!=100000000&&g[u][v]<d[v])
			{
				d[v]=g[u][v];
			}
		}
	}
	printf("%.2lf",ans);
	return 0;
}

模板模板都是模板,嗐

J题

2020蓝桥杯 省模拟赛(大学本科组)题解_第13张图片
2020蓝桥杯 省模拟赛(大学本科组)题解_第14张图片
2020蓝桥杯 省模拟赛(大学本科组)题解_第15张图片
唔这道题,怎么说,很神奇,我是瞎搞过的,啊哈哈,没思路就瞎搞
我的想法是:先枚举各个圆是否相互之间有重合,如果没有重合的两个圆,他们之间连通,然后dfs记忆化搜索(我是纯属瞎搜)
有一点一定要注意:
不能只看两个圆之间连通,要所有圆之间必须连通才可以
贴代码:

//author:wys
#include
#define ll long long
using namespace std;
int n;
ll x[40],y[40],r[40];
ll d[40][40];   //记录两个圆之间是否连通
ll vis[40];     //记录圆的选用,用于回溯
ll dp[40];  //记忆化
ll maxn;
ll dfs(int a)
{
	maxn=0;
	if(dp[a])
	return dp[a];
	vis[a]=1;
	for(int i=a+1;i<=n;i++)
	{
		if(vis[i]==1)
		continue;
		int b=0;    //标志符
		for(int j=1;j<=n;j++)  //判断选择的圆i与之前所有选择的圆是否都连通
		{
			if(vis[j]==1)
			{
				if(d[j][i]==0)
				{
					b=1;       //若与任何一个已选圆不连通,则不能选择i圆
					break;
				}
			}
		}
		if(b==0)
		{
			vis[i]=1;
			maxn=max(maxn,r[a]*r[a]+dfs(i));
			dp[a]=max(dp[a],maxn);
			vis[i]=0;
		}
	}
	if(maxn==0)       //如果是已选圆的最后一个,特殊处理
	dp[a]=r[a]*r[a];
	vis[a]=0;
	return dp[a];
}
int main() {
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i]>>r[i];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			double t=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
			if(t>=r[i]+r[j])//判断两圆是否连通
			{
				d[i][j]=1;
				d[j][i]=1;
			//	cout<
			}
			
		}
	}
	for(int i=1;i<=n;i++)
	{
		d[0][i]=1;
	}
	dfs(0);
	ll f=0;
	for(int i=0;i<=1;i++)
	{
		f=max(f,dp[i]);
	}
	cout<<f;
	return 0;
}

总体这次模拟不是很难,但我还是不能顺利ac,路途坎坷,仍需努力,各位加油!!!!!
如果有什么我思路错误的地方请大家多多指教,望指点,谢谢啦。
感谢竞码编程竞码肖老师搭建的学习平台。

你可能感兴趣的:(2020蓝桥杯 省模拟赛(大学本科组)题解)