第七届蓝桥杯大赛个人赛省赛(软件类)C/C++ 大学A组

本博客所有蓝桥杯相关代码都使用java实现
因为现在的蓝桥杯不考程序填空题了,所以程序填空题直接跳过了
我做题的网站是http://oj.hzjingma.com/site/index 里面有挺多蓝桥杯题目的,没贴题目的可以去里面找,有问题欢迎评论,其他的真题会慢慢更新
第一题

试题A:网友年龄 3'
某君新认识一网友。
当问及年龄时,他的网友说:
“我的年龄是个2位数,我比儿子大27,
如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”
请你计算:网友的年龄一共有多少种可能情况?
提示:30岁就是其中一种可能哦.
请填写表示可能情况的种数。

这个题没什么好想的直接写

package lan7A;

public class p7000 {
	public static void main(String args[]){
		int count = 0;
		for(int i = 10;i < 100;i++){
			int a = i/10;
			int b = i%10;
			if(i == b*10+a+27){
				System.out.println(i);
				count++;
			}
		}
		System.out.println(count);
	}
}

第二题 试题B:生日蜡烛 5’

package lan7A;
public class P7001 {
	public static void main(String[] args) {
//		int n = 0;
//		for(int i = 1;i < 100;i++){ // 开始年龄
//			n = 0;
//			for(int j = i;j < 150;j++){
//				n += j;
//				if(n == 236)
					System.out.println(26);
//			}
//		}
	}
}

试题C:方格填数 11’

图片我就不插了- - 有点麻烦
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。

这个题很明显,一看就是搜索的形式,我们可以用dfs来写,从第一行第二个格子开始一个数一个数填,直到填到第三行第四个就成功 ans++
(1)用vis来表示这个数是否使用过
(2)用get函数来确定这个数填在这里可以吗

package lan7A;
public class P7002 {
	static boolean vis[];
	static int ans = 0;
	static int map[][];
	static boolean get(int x,int y,int k){
		for(int i = -1;i <= 1;i++)
			for(int j = -1;j <= 1;j++){
				if(i == 0 && j== 0)
					continue;
				if(x+i>=1 && x+i <=3 && y+j>=1 && y+j <=4)
					if(Math.abs(map[x+i][y+j]-k) == 1)
						return false;
			}
		return true;
	}
	static void dfs(int x,int y){
		if(x==3&&y==4){ // 到最后一个格子了
			ans++;
			return;
		}
		if(y>4){
			dfs(x+1,1);// 已经大于4了说明一行填完了,填下一行
			return;
		}
		for(int i = 0;i < 10;i++){
			if(!vis[i] && get(x,y,i)){
				map[x][y] = i;
				vis[i] = true;
				dfs(x,y+1);
				vis[i] = false;
				map[x][y] = -10; // 注意题意的是否可以填这个数字的意思是跟别的数不连续,所以我们最好弄个负数,跟所有数都不连续,表示没使用过
			}
		}
	}
	public static void main(String args[]){
		vis = new boolean[10];
		map = new int[4][5];
		for(int i = 0;i < 4;i++)
			for(int j = 0;j < 5;j++)
				map[i][j] = -10; // 跟上面dfs中一样的道理啦
		dfs(1,2);
		System.out.println(ans);
	}
}

试题F:寒假作业 15’

这个也有图片。。我就不贴题目了

这个题的思路全排列
(1)需要注意的点就是那个除法,如果我们使用整形的话不能只判断他是否满足除以,还要保证模除是否为0 毕竟 4/3 = 1;
全排列模板,需要的可以收藏一下,蓝桥杯应该用处很大

package lan7A;
public class P7005 {
	static int a[];
	static int ans;
	static void dfs(int l,int r){
		if(l == r){
			if(a[0]+a[1]==a[2]&&a[3]-a[4]==a[5]&&a[6]*a[7]==a[8]&&a[9]/a[10]==a[11]&&a[9]%a[10]==0){
				ans++;
				return;
			}
		}
		for(int i = l;i <= r;i++){
			int t;
			t = a[l];
			a[l] = a[i];
			a[i] = t;
			dfs(l+1,r);
			t = a[l];
			a[l] = a[i];
			a[i] = t;
		}
	}
	public static void main(String[] args) {
		a = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13};
		dfs(0,12);
		System.out.println(ans);
	}
}

试题G:剪邮票 19’

如图1,12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连)

比如,图2和图3中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。

这个题可以套组合的模板跟连通块的模板,不过大家千万不要直接求dfs求,因为dfs每次只有选择一个方向,而减格子不一样。(这里博主因为太懒,实在不想放图),总之就是dfs求不出来第3个图片那种情况,因为dfs只会朝着一个方向走,这个图2个方向了

package lan7A;
public class P7006 {
	static int ans;
	static boolean map[][];
	static int xx[] = new int[]{1,-1,0,0};
	static int yy[] = new int[]{0,0,-1,1};
	static Node node[] = new Node[12];
	static int b[] = new int[5];
	static Node key[] = new Node[5]; // 保存每次选的组合
	static void dfs(int x,int y,int count){
		if(x<0 || x>=3 || y<0 || y>=4)
			return;
		if(map[x][y])
			return;
		map[x][y] = true;
		for(int i = 0;i < 4;i++){
			int dx = x+xx[i];
			int dy = y+yy[i];
			dfs(dx,dy,count);
		}
	}
	static void search(int m,int n){ // 组合模板
		for(int i = m;i <= n;i++){
			b[m-1] = i-1;
			if(m > 1)
				search(m-1,i-1);
			else{
				for(int j = 0;j < 3;j++) // 初始化地图 便于求联通块数量
					for(int k = 0;k < 4;k++)
						map[j][k] = true;
				for(int j = 0;j < 5;j++){ // 将我们选出来的点存到key中
					key[j] = new Node();
					key[j].x = node[b[j]].x;
					key[j].y = node[b[j]].y;
					map[key[j].x][key[j].y] = false;
				}
				int count = 0;
				for(int k = 0;k < 5;k++) // 判断我们组合的5个点有几个连通块
					if(!map[key[k].x][key[k].y])
						 dfs(key[k].x,key[k].y,++count);
				if(count == 1){ // 等于1说明只有1个连通块
//					for(int k = 0;k < 5;k++)
//						System.out.print(key[k].x+" "+key[k].y+" ");
//					System.out.println();
					ans++;
				}
			}
		}
	}
	public static void main(String[] args) {
		map = new boolean[4][4];
		int k = 0;
		for(int i = 0;i < 3;i++)
			for(int j = 0;j < 4;j++){
				node[k] = new Node();
				node[k].x = i;
				node[k++].y = j;
				map[i][j] = false;
			}
		search(5,12); // 12个格子中任取5个
		System.out.println(ans);
	}
}
class Node{
	int x;
	int y;
}

试题H:四平方和 21’

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多4个正整数的平方和。

如果把0包括进去,就正好可以表示为4个数的平方和。

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对44个数排序:

0 <= a <= b <= c <= d 

并对所有的可能表示法按 a,b,c,da,b,c,d 为联合主键升序排列,最后输出第一个表示法

额 直接暴力吧 当然暴力前想办法优化一下 N最大可以取5*1e6 直接4重循环当然是过不了的
(1)需要注意的是 因为是平方和 所以我们每次只需要枚举到sqrt(N)就好了
(2)4平方和,我们枚举3个就好了,最后一个可以直接用N来减去 然后求平方根 然后在判断平方和是否相等

package lan7A;
import java.util.*;
public class P7007 {
	static void get(int x){
		for(int h1 = 0;h1*h1<=x;h1++){
			for(int h2 = h1;h2*h2<=x;h2++){
				for(int h3 = h2;h3*h3<=x;h3++){
					int h4 = (int)Math.sqrt(x-h1*h1-h2*h2-h3*h3);
						if(h1*h1+h2*h2+h3*h3+h4*h4 == x){
							System.out.println(h1+" "+h2+" "+h3+" "+h4);
							return;
					}
				}
			}
		}
	}
	public static void main(String args[]){
		Scanner sc = new Scanner(System.in);
		int n =sc.nextInt();
		get(n);
	}
}

发布了32 篇原创文章 · 获赞 5 · 访问量 862

猜你喜欢

转载自blog.csdn.net/shizhuba/article/details/104885666