计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

 

 

 A. 结果填空:钟表 题库链接

分值: 5

一天蒜头君 22:28:45 开始睡觉,06:24:26 醒来之后,蒜头君在想,今天我睡了多久?

请你告诉蒜头君睡了"h:m:s",如果 h,m,sh,m,s 不足两位时,前面补 00。

例如:蒜头君睡了 1010 小时 11 分钟 00 秒,那么请输出"10:01:00"(不包含引号)。

class Main {
    public static void main(String[] args) {
        System.out.println("07:55:41");
    }
}

 

B. 结果填空:青蛙爬井 题库链接

分值: 7

有一口深度为 high 米的水井,井底有一只青蛙,它每天白天能够沿井壁向上爬 up 米,夜里则顺井壁向下滑 down 米。

若青蛙从某个早晨开始向外爬,当 high = 60405,up = 105,dow = 35,计算青蛙多少天能够爬出井口?

注意:不能简单地认为每天上升的高度等于白天向上爬的距离减去夜间下滑的距离,因为若白天能爬出井口,则不必等到晚上。

 

import java.util.Scanner;

public class 青蛙爬井 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int up = in.nextInt();
		int down = in.nextInt();
		int s=0;
		int ans = 0;
		while(true) {
			ans++;
			s+=up;
			System.out.println("h:"+s);
			if(s>=n)
				break;
			s-=down;
		}
		System.out.println(ans);
	}

}

 

class Main {
    public static void main(String[] args) {
        System.out.println("863");
    }
}

 

 C. 结果填空:倍数 题库链接

分值: 13

一天蒜头君在想,[l,r][l,r] 之间有多少个数字是 dd 的倍数呢?

但是区间 [l,r][l,r] 是 dd 的倍数的数字太多,于是聪明的蒜头君便找到了你。

当 l = 1032,r = 12302135942453,d = 234,d 的倍数有多少个呢?

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

class Main {
    public static void main(String[] args) {
        System.out.println("52573230519");
    }
}

 

 D. 结果填空:马的管辖 题库链接

分值: 17

在中国象棋中,马是走日字的。一个马的管辖范围指的是当前位置以及一步之内能走到的位置,下图的绿色旗子表示马能走到的位置。

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

如果一匹马的某个方向被蹩马脚,它就不能往这个方向跳了,如下图所示,海星的位置存在旗子,马就不能往上跳到那两个位置了:

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

那么问题来了,在一个 n×m 的棋盘内,如何用最少的马管辖住所有 n×m 个格子。比如 n=m=3 时,最少要用 5 只马才能管辖所有棋盘,一种可能的方案如下:

 计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

当 n=m=5 时,请你求出用最少马管辖的 方案个数

 

 

E. 代码填空:LIS 题库链接

分值: 9

 

答案:int k = find(0, len, a[i]);

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

import java.util.*;
import java.math.*;

public class Main {
	public static final int N = (int)1e5 + 9;
	public static int n = 0;
	public static int[] f = new int[N];
	public static int[] a = new int[N];

	public static int find(int l, int r, int x) {
		while (l < r) {
			int mid = (l + r) / 2;
			if (f[mid] < x) {
				l = mid + 1;
			} else {
				r = mid;
			}
		}
		return l;
	}

	public static int lis() {
		int len = 0;
		for (int i = 0; i < n; i++) {
			/*在这里填写必要的代码*/
            int k = find(0, len, a[i]);
			f[k] = a[i];
			if (k == len) {
				len++;
			}
		}
		return len;
	}

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		n = cin.nextInt();
		for (int i = 0; i < n; i++) {
			a[i] = cin.nextInt();
		}
		System.out.println(lis());
	}
}

 F. 程序设计:找质数 题库链接

分值: 11

一天蒜头君猜想,是不是所有的偶数(除了 2),都可以用两个质数相加得到呢?于是聪明的蒜头君就找你来验证了。

输入格式

第一行输入一个整数 t 表示测试组数。

接下来 t 行,每行一个整数 n。

输出格式

输出两个整数,因为答案可能有多个,所有要求输出的这两个整数是所有答案中字典序最小的。

数据范围

对于 30% 的数据 1≤t≤10^3。

对于 60% 的数据 1≤t≤10^5。

对于 100% 的数据 1≤t≤10^6,4≤n≤10^6,n 为偶数。

样例输入复制

3
4
8
20

样例输出复制

2 2
3 5
3 17

 

这代码超时,只有3分?

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int t = in.nextInt();
		boolean[] is = new boolean[1000000+5];
		is[1] = true;
		for(int i=2;i<=1000000;i++)
			if(!is[i])
				for(int j=2*i;j<=1000000;j+=i)
					is[j] = true;
		ArrayList<Integer> list = new ArrayList<>();
		for(int i=2;i<=1000000;i++)
			if(!is[i])
				list.add(i);
		
		int n = list.size();
//		System.out.println(n);
		while(t-->0) {
			int x = in.nextInt();
			for(int i=0;i<n;i++) {
				boolean flag = false;
				for(int j=i;j<n;j++) {
					if(list.get(i)+list.get(j)==x) {
						flag = true;
						System.out.println(list.get(i)+" "+list.get(j));
						break;
					}
					if(list.get(i)+list.get(j)>x)
						break;
				}
				if(flag)
					break;				
			}
		}
	
	}

}

 

 

 G. 程序设计:后缀字符串 题库链接

分值: 19

一天蒜头君得到 n 个字符串 si​,每个字符串的长度都不超过 10。

蒜头君在想,在这 n 个字符串中,以 si​ 为后缀的字符串有多少个呢?

输入格式

第一行输入一个整数 n。

接下来 n 行,每行输入一个字符串 si​。

输出格式

输出 n 个整数,第 ii 个整数表示以 si​ 为后缀的字符串的个数。

数据范围

对于 50% 的数据,1≤n≤10^3。

对于 100% 的数据,1≤n≤10^5。

所有的字符串仅由小写字母组成。

样例输入复制

3
ba
a
aba

样例输出复制

2
3
1
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		String[] s = new String[n];
		for(int i=0;i<n;i++)
			s[i] = reverse(in.next());
		for(int i=0;i<n;i++) {
			int ans = 0;
			for(int j=0;j<n;j++)
				if(s[j].indexOf(s[i])==0)
					ans++;
			System.out.println(ans);
		}
	}
	
	static String reverse(String x) {
		char[] ch = new char[x.length()];
		for(int i=0;i<x.length();i++)
			ch[i] = x.charAt(x.length()-1-i);
		return new String(ch);
	}

}

 

 H. 程序设计:轻重搭配 题库链接

分值: 21

 

import java.util.Arrays;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] a = new int[n];
		for(int i=0;i<n;i++)
			a[i] = in.nextInt();
		Arrays.sort(a);
		int l=0,r=n-1;
		int ans = 0;
		while(l<=r) {
			if(a[r]>=2*a[l]) {
				l++;
				r--;
				ans++;
			}
			else {
				l++;
				ans++;
			}
		}
		System.out.println(ans);
	}

}

 I. 程序设计:抠图 题库链接

分值: 23

蒜头君在做图像处理的项目时,遇到了一个问题。他需要摘取出图片中,某个黑色线框内的图片,现在请你来帮助他完成这一步,把黑色线框外的区域全部变为黑色,即只保留黑色线框内的颜色

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

蒜头君可能同时摘取多个线框,这些线框不会出现相邻,相交,包含关系,因为选择线框太多,所以蒜头君可能把其中一部分的线框少画一条边,所以这种线框是无效的。

已知图中除了黑线上的点外,图像中没有纯黑色(即像素为 00 的点)。

矩形关系说明:

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

其中下面的数据也属于相邻。

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

也就是说 0 的周围(八个方向),不会有另外一个矩形的 0。

输入格式

第一行输入测试数据的组数 N(0<N≤10)。

每组测试数据的第一行是两个整数 H,W 分别表示图片的高度和宽度 (3 \le H,W \le 500)(3≤H,W≤500)。

随后的 H 行,每行有 W 个正整数,表示该点的像素值。(像素值都在 0 到 255 之间,0 表示黑色,255 表示白色),每行整数之间使用'\t'隔开。

输出格式

以矩阵形式输出,先把黑色框之外的区域变黑,然后输出图像中各点的像素值。

数据约定

对于 30% 的数据,线框是宽度为 11 的矩形,并且线框都是完整的。

对于 60% 的数据,线框是宽度不固定的的矩形,并且线框都是完整的。

对于100% 的数据,线框可能有多个(题目保证线框不会出现相邻,相交,包含关系),线框是宽度不固定,有部分线框可能缺失其中的一条边(可以认为这种线框为无效线框)。

样例解释

对于第一组数据:

这是一个完整的矩形,所以会保留线框内的颜色,保留下 (3,2),(3,3)(3,2),(3,3) 的像素值。

对于第二组数据:

只有一个矩形,这个矩形不是完成整的矩形,所有是无效线框,所以没有像素值被保留。

对于第三组数据:

有多个矩形,且矩形都满足不相邻,相交,包含的关系。

样例输入复制

3
4 5
1	0	0	0	1
1	0	1	0	1
1	0	1	0	1
1	0	0	0	1
5 6
1	1	1	1	1	1
1	0	1	0	1	1
1	0	1	0	1	1
1	0	0	0	1	1
1	1	1	1	1	1
10 10
1	1	1	1	1	1	1	1	1	1
1	0	0	0	0	0	1	0	1	0
1	0	0	0	0	0	1	0	1	0
1	0	0	1	0	0	1	0	0	0
1	0	0	0	0	0	1	1	1	1
1	0	0	0	0	0	1	1	1	1
1	1	1	1	1	1	1	1	1	1
1	1	1	0	0	0	1	0	0	0
1	1	1	0	1	0	1	0	1	0
1	1	1	0	0	0	1	0	0	0

样例输出复制

0 0 0 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0

 一模一样的java代码会超时呵呵,还有就是末尾空格会爆0

#include<iostream>
#include<cstdio>
using namespace std;

int a[505][505];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
int n,m,t;

void dfs(int x,int y) {
	a[x][y] = 0;
	for(int i=0;i<4;i++)
		if(x+dx[i]>=0 && x+dx[i]<n && y+dy[i]>=0 && y+dy[i]<m && a[x+dx[i]][y+dy[i]]!=0)
			dfs(x+dx[i],y+dy[i]);
}

int main() {
	cin>>t;
	while(t-->0) {
		cin>>n>>m;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				scanf("%d",&a[i][j]);
		for(int i=0;i<n;i++) {
			if(a[i][0]!=0)
				dfs(i,0);
			if(a[i][m-1]!=0)
				dfs(i,m-1);
		}
		for(int i=0;i<m;i++) {
			if(a[0][i]!=0)
				dfs(0,i);
			if(a[n-1][i]!=0)
				dfs(n-1,i);
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++)
					 printf("%d%c", a[i][j], " \n"[j == m]);

//				cout<<a[i][j]<<" ";
//			cout<<endl;
		}
	}
	return 0;
}

 

 J. 程序设计:蒜厂年会 题库链接

分值: 25

在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 n 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币。但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币。因为这些数字都是可见的,所以大家都是不会出现的赔的情况。

游戏规则:每人只能抓一次,只能抓取一段连续的纸团,所有纸团上的数字和就是你可以获得的蒜币。

蒜头君作为蒜厂的一员在想,我怎么可以获得最多的蒜币呢?最多能获取多少蒜币呢?

因为年会是发奖,那么一定有大于 0 的纸团。

输入格式

第一行输入一个整数 n,表示有 n 个纸团。

第二行输入输入 n 个整数 ai​,表示每个纸团上面写的数字(这些纸团的输入顺序就是环形桌上纸团的摆放顺序)。

输出格式

输出一个整数,表示蒜头君最多能获取多少蒜币。

计蒜客2019蓝桥杯省赛B组模拟赛(一)题目及解析

 

10个样例过8个样例的代码

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] a = new int[2*n+5];
		for(int i=0;i<n;i++) {
			a[i] = in.nextInt();
			a[n+i] = a[i];
		}
		long len =0,s=0,max=0;
		for(int i=0;i<2*n;i++) {
			s+=a[i];
			len++;
			if(s<0) {
				s=0;
				len=0;
			}
			if(len>n) {
				s-=a[i-n];
				len--;
			}
			max = Math.max(max,s);
		}
		System.out.println(max);
		
	}

}