2019年第十届蓝桥杯大赛软件类省赛C/C++B组

A题:组队

答案:490

数据:

1 97 90 0 0 0
2 92 85 96 0 0
3 0 0 0 0 93
4 0 0 0 80 86
5 89 83 97 0 0
6 82 86 0 0 0
7 0 0 0 87 90
8 0 97 96 0 0
9 0 0 89 0 0
10 95 99 0 0 0
11 0 0 96 97 0
12 0 0 0 93 98
13 94 91 0 0 0
14 0 83 87 0 0
15 0 0 98 97 98
16 0 0 0 93 86
17 98 83 99 98 81
18 93 87 92 96 98
19 0 0 0 89 92
20 0 99 96 95 81

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
int a[25],b[25],c[25],d[25],e[25];
int main(){
	int i,j,k,t,f,h;
	for(int i=0;i<20;i++){
		cin>>h;
		cin>>a[i]>>b[i]>>c[i]>>d[i]>>e[i];
	}
	int sum=-1;
	for(i=0;i<20;i++){
		for(j=0;j<20;j++){
			for(k=0;k<20;k++){
				for(t=0;t<20;t++){
					for(f=0;f<20;f++){
						if(i!=j&&i!=k&&i!=t&&i!=f&&j!=k&&j!=t&&j!=f&&k!=t&&k!=f&&t!=f){
							int num=a[i]+b[j]+c[k]+d[t]+e[f];
							sum=max(sum,num);
						}
					}
				}
			}
		}
	}
	cout<<sum<<endl;
} 

 

第二题:

答案:BYQ

2019=26*26*2+26*25+17;

第三题:

答案:4659

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
int main(){
	long long a=1,b=1,c=1,h=0;
	for(int i=4;i<=20190324;i++){
		h=(a+b+c)%10000;
		a=b;b=c;c=h;
	}
	cout<<h<<endl;
} 

第四题:

答案:40785

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
int judge(int x){
	while(x){
		int t=x%10;
		x/=10;
		if(t==2||t==4){
			return 0;
		} 
	}
	return 1;
}
int main(){
	int a,b,c,num=0,x;
	for(a=1;a<2019;a++){
		for(b=a+1;b<2019;b++){
			c=2019-a-b;
			if(c<b)  break;
			if(a!=b&&b!=c&&a!=c&&judge(a)&&judge(b)&&judge(c)){
			num++;
			}
		}
	}
	cout<<num<<endl;
} 

第五题:迷宫

答案:186步

DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

注意:

输入数据不能用int mp[50][50]表示,因为输入的‘0’与'1'没有空格

定义结构体数组:结构体内部不能存在函数!!!!!

direction dir[4]={{1,0,'D'},{0,-1,'L'},{0,1,'R'},{-1,0,'U'}};

注意方向的表示,非常容易错误:int dir[4][2] ={{-1,0},{1,0},{0,-1},{0,1}}; //上下左右

{-1,0}表示行往上一个单位,列不变  ----方向:上
{0,-1}表示列减少一个单位,行不变  ----方向:左

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
	int x,y,step;
	string s;
	node(int xx,int yy,int step1,string ss){
		x=xx;
		y = yy;
		step = step1;
		s = ss;
	}
};
struct direction{
	int x,y;
	char c;
};

char mp[55][55];
int vis[55][55];
struct direction dir[4]={{1,0,'D'},{0,-1,'L'},{0,1,'R'},{-1,0,'U'}};

void bfs(int a,int b){
	queue<node> q;
	memset(vis,0,sizeof(vis));
	q.push(node(a,b,0,""));
	vis[a][b]=1;
	while(!q.empty()){
		node fr=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int x=fr.x+dir[i].x;
			int y=fr.y+dir[i].y;
			if(x>=0&&x<n&&y>=0&&y<m&&(!vis[x][y])&&(mp[x][y]=='0')){
				q.push(node(x,y,fr.step+1,fr.s+dir[i].c));
				vis[x][y]=1;
				if(x==n-1&&y==m-1){
			    cout<<fr.s+dir[i].c<<endl;
			    cout<<fr.step+1<<endl;
			    break;
		        }
			}
		}
	}
}
int main(){
   	scanf("%d%d",&n,&m);//30行50列 
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++)
		cin>>mp[i][j];
	}
	bfs(0,0);
	return 0;
}

 F: 特别数的和 

#include<bits/stdc++.h>
using namespace std;
int n;
long long num;
//包含0,1,2,9 
int solve(int x){
	while(x){
		int t=x%10;
		x/=10;
		if(t==0||t==1||t==2||t==9)	return 1;
	}
	return 0;
}
int main(){
	cin>>n;
	num=0;
	for(int i=1;i<=n;i++){
		if(solve(i)) num+=i;
	} 
	cout<<num<<endl;
}

G:完全二叉树的权值 

#include<bits/stdc++.h>
using namespace std;
int N;//100000 
long long ans[20];//深度最多为20---记录每层值的总和 
#define inf 0x7f7f7f7f
int main(){
	cin>>N;
	//每层的深度 
	for(int i=0;i<=20;i++) ans[i]=0;
	int d=1,t;
	for(int i=1;i<=N;i++){
		cin>>t;
		if(i>=pow(2,d)){
			d++;//表示进入下一个深度 
		}
		ans[d]+=t;
	}
   //cout<<d<<endl;
	long long maxans=-inf;
	int ans_d=0;
	for(int i=0;i<=d;i++){
		if(maxans<ans[i]){
			maxans=ans[i];
			ans_d=i;
		}
	}
	cout<<ans_d<<endl;
}

 H: 等差数列 

我的垃圾思路:求出数列的最小间距d_min,d_min与等差间距d一定存在d*k=d_min之间的关系。

由于我们要使项数最小,所以我们要使k尽量小,所以我们遍历k从1到d_min

另外我们需要特判当d=0的情况,项数为N

更优的思路:

排序,然后对两个数的距离进行求最大公因子。

思路一代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
#define inf 0x7f7f7f7f
int a[maxn],N,d_min;
int solve(int k){//判断d是否符合数组的d 
	int d=d_min/k;
	for(int i=0;i<N;i++){
		if(((a[i]-a[0])%d)!=0){
			return 0;
		}
	}
	return 1;
}
int main(){
	cin>>N; 
	for(int i=0;i<N;i++) 
	cin>>a[i];
	sort(a,a+N);
	//等差数列的d与最小间距d_min的关系:d*k=d_min
	d_min=inf;//求出两数间距的最小值 
	for(int i=0;i<N-1;i++){
		int t=a[i]-a[i+1];
		if(t<0) t=-1*t;
		d_min=min(d_min,t);
	} 
	int d;//求出该等差数组的d 
	if(a[0]==a[1]){//特判,d=0的情况 
		cout<<N<<endl;
	} 
	else{
	for(int k=1;k<=d_min;k++){
		if(solve(k)){
			d=d_min/k;
			//cout<<"d:"<<d<<endl; 
			int cnt=(a[N-1]-a[0])/d+1;
			cout<<cnt<<endl;
			break;
		}
	} 
}
}

思路二代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
#define inf 0x7f7f7f7f
int a[maxn],N,d;
int ans[maxn];
int gcd(int a,int b)   //最大公约数
{
    if(b==0)  return a;
    else return gcd(b,a%b);
}   
int main(){
	cin>>N; 
	for(int i=0;i<N;i++) 
	cin>>a[i];
	sort(a,a+N);
	if(a[0]==a[1]) cout<<N<<endl;
	else if(N==1)  cout<<N<<endl;
	else{
	for(int i=0;i<N-1;i++){
		ans[i]=a[i+1]-a[i];
	} 
	d=ans[0];
	for(int i=1;i<N-1;i++){
		d=gcd(d,ans[i]);
	}
	int cnt=0;
	cnt=(a[N-1]-a[0])/d+1;
	cout<<cnt<<endl;
    }
}

 I: 后缀表达式 

错误策略:前面数字大的使用加号,后面值小的都采用减号

//这个题如果用贪心的话可能解出的答案是错误的 如果给出的数字为1 2 3 4 5 6 7 + + + - - - 贪心算出来的是7+6+5+4-3-2-1 = 16 
而最大的其实是7+6+5+4-(1-3-2)=26

正确策略:输入数中的负数个数num与m的关系:

若num>=m   采用原策略,前(N+1)大加,后m小减

错误代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
int n,m;
int a[maxn*2];
int cmp(int x,int y){
	return x>y;
}
long long ans=0;
int main(){
	cin>>n>>m;
	for(int i=0;i<n+m+1;i++){
		cin>>a[i];
	}
	sort(a,a+n+m+1,cmp);//从大到小排序
	//前面数字大的使用加号,后面值小的都采用减号
	ans=0;
	for(int i=0;i<=n;i++){
	ans+=a[i];	
	} 
	for(int i=n+1;i<=n+m;i++){
	ans=ans-a[i];	
	}
	cout<<ans<<endl;	
}

正确代码:

#include<bits/stdc++.h>
using namespace std;
//这个题如果用贪心的话可能解出的答案是错误的 如果给出的数字为1 2 3 4 5 6 7 + + + - - - 贪心算出来的是7+6+5+4-3-2-1 = 16 
//而最大的其实是7+6+5+4-(1-3-2)=26
#define maxn 100010
int n,m;
int a[maxn*2];
int cmp(int x,int y){
	return x>y;
}
long long ans=0;
int main(){
	cin>>n>>m;
	int num=0;
	for(int i=0;i<n+m+1;i++){
		cin>>a[i];
		if(a[i]<0) num++;
	}
	sort(a,a+n+m+1,cmp);//从大到小排序
	//前面数字大的使用加号,后面值小的都采用减号
	if(num>=m){
	ans=0;
	for(int i=0;i<=n;i++) ans+=a[i];//前n大加 
	for(int i=n+1;i<=n+m;i++) ans=ans-a[i];	//后m小减 
	cout<<ans<<endl;
    }
    else{
    ans=-1*a[n+m];//加所有数的绝对值,减去最小的数 
	for(int i=0;i<n+m;i++){
	if(a[i]<0)  ans=ans-a[i];
	else  ans=ans+a[i];
	}	
	cout<<ans<<endl;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值