第九届蓝桥杯b组java

第一题:

标题:第几天

2000年的1月1日,是那一年的第1天。

那么,2000年的5月4日,是那一年的第几天?

注意:需要提交的是一个整数,不要填写任何多余内容。

答案:125

代码:

package 第九届蓝桥杯;

public class Main01 {
	private static int month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
	public static void main(String[] args) {
		/*
		 * 2000年的1月1日,是那一年的第1天。 那么,2000年的5月4日,是那一年的第几天?
		 */
		System.out.println(ok());
	}
	public static boolean run(int yead) {
		if(yead%4==0&&yead%100!=0||yead%400==0) {
				return true ;
		}
		return false;
	}
	public static int ok() {
		int ans = 1;
		if(run(2020)) {
			month[2] = 29 ;
		}
		int tx = 1; //月
		int ty = 1; //日
		while(true) {
			ty++;
			ans++;
			if(ty>month[tx]) {
				tx++;
				ty = 1;
			}
			if(tx==5&&ty==4) {
				break;
			}
		}
		return ans;
	}
}

第二题 :

标题:方格计数

如图p1.png所示,在二维平面上有无数个1x1的小方格
在这里插入图片描述
我们以某个小方格的一个顶点为圆心画一个半径为1000的圆。
你能计算出这个圆里有多少个完整的小方格吗?

注意:需要提交的是一个整数,不要填写任何多余内容。

答案: 3137548
代码:

package 第九届蓝桥杯;

public class Main02 {
	private static int R = 1000;
	private static long ans ;
	//第一象限所有方格一个一个查。。。
	public static void main(String[] args) {
		//枚举第一象限的坐标
		for(int i=1;i<=1000;i++) {
			for(int j=1;j<=1000;j++) {
				if(i*i+j*j<=R*R) {
					ans++;
				}
			}
		}
		System.out.println(ans*4);
	}

}

第三题:

标题:复数幂
设i为虚数单位。对于任意正整数n,(2+3i)^n 的实部和虚部都是整数。
求 (2+3i)^123456 等于多少? 即(2+3i)的123456次幂,这个数字很大,要求精确表示。
答案写成 “实部±虚部i” 的形式,实部和虚部都是整数(不能用科学计数法表示),中间任何地方都不加空格,实部为正时前面不加正号。(2+3i)^2 写成: -5+12i,
(2+3i)^5 的写成: 122-597i

注意:需要提交的是一个很庞大的复数,不要填写任何多余内容。

思路:数据不是一般的大啊,编译器的打印台都打印不出来,我把他打到文件中才看到。
代码:

package 第九届蓝桥杯;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.math.BigInteger;

public class Main03 {
	public static void main(String[] args) throws FileNotFoundException {
		PrintStream pp=new PrintStream(new FileOutputStream("F:\\lao\\f.txt"));
		System.setOut(pp); //打印重定向 打印到文件中
		 BigInteger a = new BigInteger("2"); //存实部
		 BigInteger b = new BigInteger("3");//存虚部
		 BigInteger c = new BigInteger("2");//存总实部
		 BigInteger d = new BigInteger("3");//存总虚部
		for(int i=1;i<123456;i++) {
			BigInteger ta = c;
			BigInteger tb = d;
			c = a.multiply(ta);
			c = c.subtract(b.multiply(tb));
			d = b.multiply(ta);
			d = d.add(a.multiply(tb));
		}
		System.out.println(c.toString()+"\n---------------------------------------------------------------------------------------------------------- ---"+d.toString());
		pp.close();
	}
}

第四题:

标题:测试次数
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
请填写这个最多测试次数。

注意:需要填写的是一个整数,不要填写任何多余内容。

答案:19

代码:

package 第九届蓝桥杯;

public class Main04 {
	private static int n = 3 ;
	private static int m = 1000;
	private static int[][] dp = new int[n+1][m+1];
	public static void main(String[] args) { 
		//我们假设第一次站在k层楼摔 
		//dp[i][j]代表有i部手机j层楼时摔坏所有手机的情况下 测试任意抗摔系数的最多次数 
		//dp[i][j]=min(dp[i][j],max(dp[i-1][k-1],dp[i][j-k)); 
		//状态转移方程表示 :
				//1.不同k之间取最小值 
				//2.同一 k之间的不同情况取最大值,避免遗漏(如果在这里取了最小值,那么意味着需要更多测试次数情况的测试不到) 
		//dp[i][j-k]表示还剩下j-k层楼没有测试,在这里不要想当然的认为楼层越高越容易摔碎,我们需要的只是能测试所有的楼层即可
		
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				dp[i][j] = j; //初始化 最坏的情况莫过于此
			}
		}
		
		for(int i=2;i<=n;i++) { //一部手机时 我们只能从1层开始一层一层的摔
			for(int j=1;j<=m;j++) { //假设一共有 j 层楼
				for(int k=1;k<=j;k++) { //假设我们从k层摔
					dp[i][j] = Math.min(dp[i][j], Math.max(dp[i-1][k-1],dp[i][j-k] )+1);
				}
			}
		}
		
		System.out.println(dp[3][1000]);
	}
}

第五题 :快速排序
蓝桥杯取消代码填空了,这题就不写了。

第六题:

标题:递增三元组
给定三个整数数组
A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:

  1. 1 <= i, j, k <= N
  2. Ai < Bj < Ck

【输入格式】
第一行包含一个整数N。
第二行包含N个整数A1, A2, … AN。
第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。
对于30%的数据,1 <= N <= 100
对于60%的数据,1 <= N <= 1000
对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000
【输出格式】
一个整数表示答案

【输入样例】
3
1 1 1
2 2 2
3 3 3

【输出样例】
27

思路:以b数组为基准 二分

代码:

package 第九届蓝桥杯;



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

public class Main06 {
	private static int n ;
	private static long ans;
	private static int[] a;
	private static int[] b;
	private static int[] c;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		a = new int[n];
		b = new int[n];
		c = new int[n];
		for(int i=0;i<n;i++) {
			a[i] = sc.nextInt();
		}
		for(int i=0;i<n;i++) {
			b[i] = sc.nextInt();
		}
		for(int i=0;i<n;i++) {
			c[i] = sc.nextInt();
		}
		Arrays.sort(a);
		Arrays.sort(b);
		Arrays.sort(c);
		for(int i=0;i<b.length;i++) {
			ans+=binMin(b[i])*binMax(b[i]);
		}
		System.out.println(ans);
	}
	public static long binMax(int x) {
		int min = 0;
		int max = c.length;
		int mid =(min+max)/2;
		while(min<max) {
			if(c[mid]>x) {
				max = mid;
			}else if(c[mid]<=x) {
				min = mid+1;
			}
			mid = (min+max)/2;
		}
		return c.length-max;
	}
	public static long binMin(int x) { //寻找小于x的最大值
		int min = 0;
		int max = a.length;
		int mid = (max+min)/2;
		while(min<max) {
			if(a[mid]<x) {
				min = mid+1;
			}else if(a[mid]>=x) {
				max = mid;
			}
			mid = (max+min)/2;
		} 
		return max;
	}
}

第七题

标题:螺旋折线
找规律 ,第九届蓝桥杯b组,之前写过 ,有点麻烦就不写了。。。

第八题

标题:日志统计
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是:
ts id
表示在ts时刻编号id的帖子收到一个"赞"。
现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。
具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。
给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。

【输入格式】

第一行包含三个整数N、D和K。
以下N行每行一条日志,包含两个整数ts和id。

对于50%的数据,1 <= K <= N <= 1000
对于100%的数据,1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000

【输出格式】
按从小到大的顺序输出热帖id。每个id一行。

【输入样例】

7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3

【输出样例】
1
3
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

思路:双指针

package 第九届蓝桥杯;

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

public class Main08 {
	//暴力会超时 采用双指针 i 和 j 维护一个不大于d的区间
	//时间复杂度 O(nlogn)
	private static int n ;
	private static int d;
	private static int k;
	private static megss[] m;
	private static int[] count = new int[1000005];;
	private static boolean[] flag = new boolean[1000005];;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		d = sc.nextInt();
		k = sc.nextInt();
		m = new megss[n+1];
		for(int i=0;i<n;i++) {
			int t = sc.nextInt();
			int id=sc.nextInt();
			m[i] = new megss(t,id);
		}
		Arrays.sort(m,0,n);
		for(int i=0,j=0;i<n;i++) {
			int id = m[i].id;
			count[id]++;
			while(m[i].t-m[j].t>=d) {
				count[m[j].id]--;
				j++;
			}
			if(count[id]>=k) {
				flag[id] = true;
			}
		}
		for(int i=0;i<1000001;i++) {
			if(flag[i]) {
				System.out.println(i);
			}
		}
	}
}
class megss implements Comparable<megss>{
	int  t ;
	int id;
	
	public megss() {
		super();
	}

	public megss(int t, int id) {
		super();
		this.t = t;
		this.id = id;
	}


	@Override
	public int compareTo(megss o) {
		// TODO 自动生成的方法存根
		return this.t-o.t;
	}


	
}

第九题

标题:全球变暖

你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:

.##…
.##…
…##.
…####.
…###.

其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:




…#…


请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】

第一行包含一个整数N。 (1 <= N <= 1000)

以下N行N列代表一张海域照片。

照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7

.##…
.##…
…##.
…####.
…###.

【输出样例】
1

思路:dfs搜一下就好了
代码:

package 第九届蓝桥杯;

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

public class Main09 {
	private static int n ;
	private static int aa ;
	private static int bb ;
	private static int[] ans;
	private static int[][] book ;
	private static String[] str ;
	private static char[][] ch ;
	private static int[][] next = {{0,1},{1,0},{0,-1},{-1,0}};
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		str = new String[n];
		ch  = new char[n][n];
		ans = new int[1000005];
		book = new int[n][n];
		for(int i=0;i<n;i++) {
			str[i] = sc.next();
			ch[i]  =str[i].toCharArray();
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(book[i][j]==0&&ch[i][j]=='#') { //是陆地且未被标记
					book[i][j]=++aa;
					dfs(i,j,aa);
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(ch[i][j]=='#'&&ok(i,j)) {
					book[i][j]=0;
				}
			}
		}
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				if(book[i][j]!=-1) {
					ans[book[i][j]]++;
				}
			}
		}
		for(int i=1;i<ans.length;i++) {
			if(ans[i]!=0) {
				bb++;
			}
		}
		System.out.println(aa-bb);
	}
	public static void dfs(int x,int y,int a) {
		for(int i=0;i<4;i++) {
			int tx = x+next[i][0];
			int ty = y+next[i][1];
			if(tx>=0&&tx<n&&ty>=0&&ty<n&&ch[tx][ty]=='#'&&book[tx][ty]==0) {
				book[tx][ty] = a;
				dfs(tx,ty,a);
			}
		}
	}
	public static boolean ok(int x,int y) {
		for(int i=0;i<4;i++) {
			int tx = x+next[i][0];
			int ty = y+next[i][1];
			if(ch[tx][ty]=='.') {
				return true;
			}
		}
		return false;
		
	}
}

posted @ 2020-06-07 13:03  键盘_书生  阅读(60)  评论(0编辑  收藏  举报