本博客所有蓝桥杯相关代码都使用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);
}
}