蓝桥杯31天冲刺之六 [java]

文章目录

  • 巧排扑克牌
  • 质数拆分
  • 日志统计
  • 递增三元组
  • 外卖店优先级

巧排扑克牌

蓝桥杯31天冲刺之六 [java]_第1张图片

题目链接: https://www.lanqiao.cn/problems/735/learning/

这个题直接使用代码模拟就ok了,说实话如果考场上看到了我会直接自己抽牌算hhhh

由于知道最后的顺序和他抽的过程,那么我们就可以反着去模拟回初始状态,这里定义一个数组表示所有的牌,并且定义一个变量bottom指向目前的牌底,也就是说在bottom之前的元素实际都已经被抽出去,然后我们反向的过程就是从牌顶部(数组最后一个元素)取牌放到当前的底部位置,直到bottom指向数组开始位置

package daily;

import java.util.Arrays;

/**
 * https://www.lanqiao.cn/problems/735/learning/
 * 
 * @author Jia
 *
 */
public class day3_13_1 {
	public static void main(String[] args) {
		// 这里直接定义字符数组了,所以没法定义10,用T替代了,也可以直接定义为字符串数组
		char[] poke = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
		int bottom = 12;// 标记现在的底部
		for (int i = 0; i < poke.length; i++) {
			pushBack(poke, bottom);
			bottom--;
		}
		// 使用API输出时候会被[]括起来,使用replace去掉,然后将数组中的T换成10
		System.out.println(Arrays.toString(poke).replace("T", "10").replace("[", "").replace("]", ""));
	}

	/**
	 * 把牌顶的元素放回牌底。就相当于把数组最后一个元素放到bottom指示的地方,同时把bottom之后的字符向后挪一位
	 * 
	 * @param poke
	 * @param bottom
	 */
	private static void pushBack(char[] poke, int bottom) {
		char temp = poke[poke.length - 1];
		for (int i = poke.length - 1; i > bottom; i--) {
			poke[i] = poke[i - 1];
		}
		poke[bottom] = temp;
	}
}

质数拆分

蓝桥杯31天冲刺之六 [java]_第2张图片

题目链接: https://www.lanqiao.cn/problems/809/learning/

这题不太会,反正是dp,照不出来递推公式,我这个推出来有点太大了,正确答案应该是14位数

可以看看我这哪有问题。。前面13项调试都是正确的,后面的就不知道了

我的想法是从前往后看有多少二质数组合可以拼成x数,然后利用这个公式往后一直推下去,比如7的话,就需要查看1+6,2+5,3+4,然后可能性就是1+后面三种的组合数(两个数的可能性的乘积)

package daily;

import java.util.Arrays;

/**
 * https://www.lanqiao.cn/problems/809/learning/
 * 
 * @author Jia
 *
 */
public class day3_13_2_wa {

	public static void main(String[] args) {
		int n = 2019;
		long ans = 0l;
		long[] sumIndex = constructPrimaryArr(n);
		for (int i = 1; i < sumIndex.length; i++) {
			for (int j = 1; j < i; j++) {
				if (j < i - j) {
//					System.out.println(i + " " + j + " " + (i - j));
//					System.out.println(sumIndex[i] + " " + sumIndex[j] + " " + sumIndex[i - j]);
					sumIndex[i] += sumIndex[j] * sumIndex[i - j];
//					System.out.println(sumIndex[i]);
				} else {
					break;
				}
			}
		}
		for (int i = 0; i < sumIndex.length; i++) {
			System.out.println(i + "\t" + sumIndex[i]);
		}
		System.out.println(sumIndex[2019]);
	}

	/**
	 * 构造一个素数数组
	 * 
	 * @param n
	 * 
	 * @return
	 */
	private static long[] constructPrimaryArr(int n) {
		long[] arr = new long[n + 1];
		Arrays.fill(arr, 1l);
		arr[0] = 0l;
		arr[1] = 0l;
		for (int i = 2; i < arr.length; i++) {
			if (arr[i] == 1) {
				int j = i + i;
				while (j < arr.length) {
					arr[j] = 0l;
					j += i;
				}
			}
		}

		return arr;
	}
}

日志统计

蓝桥杯31天冲刺之六 [java]_第3张图片

题目链接:https://www.lanqiao.cn/problems/179/learning/

这个题整体处理起来比较麻烦,但是思路不是很难,整体使用的还是贪心思想

前面数据处理的方法也有其他的,不一定非要使用HashMap,我用map主要是因为查找比较方便。

具体的处理逻辑在53-62行,对于每个帖子,通过一个大小为D的时间段去统计总共有多少点赞,如果使用双层循环的话很可能会超时,所以我是通过记录当前统计的这段时间的开始时间点,然后判断当前时间点的差值与开始时间点的差值是不是大于D,如果不大于D点赞数加一,如果大于D则要通过调整开始时间保证开始时间到当前节点的时间小于D即可。

package daily;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;

/**
 * https://www.lanqiao.cn/problems/809/learning/
 * 
 * @author Jia
 *
 */
public class day3_13_3 {
	public static void main(String[] args) {
		// 读入数据
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int D = sc.nextInt();
		int K = sc.nextInt();
		Map<Integer, PostInfo> map = new HashMap<>();// 方便在获得到一个点赞的时候知道是哪一个帖子的
		for (int i = 0; i < N; i++) {
			int ts = sc.nextInt();
			int id = sc.nextInt();

			if (map.containsKey(id)) {
				map.get(id).add(ts);
			} else {
				PostInfo PostInfo = new PostInfo();
				PostInfo.add(ts);
				map.put(id, PostInfo);
			}
		}
		sc.close();

		// 存储热帖的id
		ArrayList<Integer> ansList = new ArrayList<>();

		// 遍历所有人的被点赞集合,统计热帖
		for (Entry<Integer, PostInfo> entry : map.entrySet()) {
			// 查看所有数据
			// System.out.println(entry.getKey() + " " + entry.getValue());
			// 得到点赞列表并排序
			ArrayList<Integer> tsList = entry.getValue().ts;
			tsList.sort((a, b) -> a - b);// lambda表达式,传入(a,b),返回a-b,不熟悉的话可以直接传入匿名的Comparable也可以

			int sum = 1;// 当前时间段内点赞总数
			int beginTime = tsList.get(0);// 开始时间
			int beginIndex = 0;// 开始时间的下标,用于判断下一个时间段开始时间
			int max = 1;// 记录不同时间段内的最大点赞数

			for (int i = 1; i < tsList.size(); i++) {
				// 当该节点的时间超出当前统计的时间段时,需要将时间段向后推,直到包含该时间点
				while (tsList.get(i) - beginTime >= D) {
					sum--;
					beginIndex++;
					beginTime = tsList.get(beginIndex);
				}
				sum++;
				max = Math.max(max, sum);
			}

			// 如果大于等于K,说明是热帖
			if (max >= K) {
				ansList.add(entry.getKey());
			}
		}

		// 将结果排序后输出
		ansList.sort((a, b) -> a - b);
		for (int i = 0; i < ansList.size(); i++) {
			System.out.println(ansList.get(i));
		}
	}
}

class PostInfo {
	ArrayList<Integer> ts = new ArrayList<>();// 点赞时间列表

	public void add(int t) {
		ts.add(t);
	}

	@Override
	public String toString() {
		return ts.toString();
	}

}

递增三元组

蓝桥杯31天冲刺之六 [java]_第4张图片

题目链接: http://lx.lanqiao.cn/problem.page?gpid=T2728

呃,这个题没完全过,这个方法还是有点类似于暴力求解的,过了7/8的测试数据,最后一个估计是数据量太大了

开始就想的是肯定不能暴力求解,如果暴力遍历肯定超时,然后就只能是先对三个数组排序,然后定义数组

package daily;

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

/**
 * http://lx.lanqiao.cn/problem.page?gpid=T2728
 * 
 * @author Jia
 *
 */
public class day3_13_4 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[] A = new int[N];
		int[] B = new int[N];
		int[] 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();
		}
		sc.close();

		// 对A、B、C进行排序
		Arrays.sort(A);
		Arrays.sort(B);
		Arrays.sort(C);

		long ans = 0L;// 记录最后结果
		int[] ansB = new int[N];// B的该位比A的多少个数字大
		int preA = A.length - 1;
		// 统计B每位比A大的数量
		for (int i = B.length - 1; i >= 0; i--) {
			for (int j = preA; j >= 0; j--) {
				if (B[i] > A[j]) {
					preA = j;
					ansB[i] = j + 1;
					break;
				}
			}
		}

		// 逐位比较C和B,如果C比B大,ans加上ansB对应的数字(这里其实还可以优化的,让B从上一次结束的地方开始,但是总是有BUG,就只能这样了)
		for (int i = 0; i < C.length; i++) {
			for (int j = 0; j < B.length; j++) {
				if (C[i] > B[j]) {
					ans += ansB[j];
				}
			}
		}

		System.out.println(ans);

	}
}

外卖店优先级

题目链接:https://www.lanqiao.cn/problems/184/learning/

你可能感兴趣的:(蓝桥杯,java,蓝桥杯,算法)