第一题. 38红包
问题简述:
从1到2025,有多少个数是3或者8或者38的倍数。
问题解答:不多说了,直接上代码
代码:
public class Main{
public static void main(String[] args) {
int count = 0;
for (int i = 1; i <= 2025; i++) {
if (i % 3 == 0 || i % 8 == 0 || i % 38 == 0) {
count++;
}
}
System.out.println(count);
}
}
第二题:祝福语
问题简述:
现有一个S字符串,求出T字符串,T满足条件:
1.不是S字符串的子串 2.字典序最小
问题解答:
思考:
我们先思考,字典序要最小,那么T一定都是a。
例如aab
我们可以想到最小的字典序子串
a - > aa - > aaa
那么前两个没有满足条件,我们输出aaa;所以我们得出结论:
要保证T不是S的子串,我们的 T 中 a 的数量 一定是( S 中 连续a 的数量 + 1)
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
scanner.close();
int cnt = 0, tmp = 0;
for (char ch : s.toCharArray()) {
if (ch == 'a') {
tmp++;
} else {
cnt = Math.max(cnt, tmp);
tmp = 0;
}
}
cnt = Math.max(cnt, tmp);
System.out.println("a".repeat(cnt + 1));
}
}
第三题:社区服务
问题简述:
给你 n 个数字(只能是01)代表二进制数字,求出0 旁边 距离最近的1 的 距离。
问题解答:
思考:
1010100
我们可以看到,有些0,左边也有1,右边也有1,那距离最近的肯定是二者最小。
即Math.min(left,right);
1.那我们可以先考虑 各个 0距离左边 最近的 1 的距离。然后用一个数组ds记录.
我们用一个last 记录左边(前面)最新的 1 的值。(从左到右扫)
2.然后我们考虑 各个 0距离右边 最近的 1 的距离。然后更新数组ds的记录.
我们用一个last 记录右边(前面)最新的 1 的值。(从右到左扫)
然后就是ds里 不是0 的 就是结果。
代码:
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String S = scanner.next();
scanner.close();
int[] ds = new int[n];
int last = -1;
for (int i = 0; i < n; i++) {
if (S.charAt(i) == '1') {
last = i;
} else {
ds[i] = (last == -1) ? Integer.MAX_VALUE : (i - last);
}
}
last = -1;
for (int i = n - 1; i >= 0; i--) {
if (S.charAt(i) == '1') {
last = i;
} else {
int rightDist = (last == -1) ? Integer.MAX_VALUE : (last - i);
ds[i] = Math.min(ds[i], rightDist);
}
}
for (int i = 0; i < n; i++) {
if (S.charAt(i) == '0') {
System.out.print((ds[i] == Integer.MAX_VALUE ? -1 : ds[i]) + " ");
}
}
}
}
第四题:表演队
问题简述:
我们需要从N个数中,选出K个数,使得最小差异值 之和(计算公式在题目里)最小。
问题解答:
思考:
由于这种题目结果并没有和顺序有关系,所以我们先排序。
排序之后,我们发现,相邻两个的差异值最小。 -----1.
那怎么选取K个,能使得他们的差异值之和最小。
其实结论:排序后选择连续的 K 个数可以使得总的绝对差之和最小
这里我就不推导了,大家可以举个例子思考一下。
那我们知道这个结论了,那我们就可以求出这题了。这题就变成了求出连续K个数的绝对差和的最小
连续k个数我们可以想到滑动窗口,那我们在求k个数的绝对差的和
即S1,S2,S3,S4,S5,S6,S7....SK
S = (S1 - S2) + (S1 - S3) + (S1 - S4) +....+ (S1 - SK) + (S2 - S3) +.. + (S2 - SK) + ...
= (S2 + S3 + S4 + ...+ SK ) - (K - 1) * S1 +
(S3 + S4 + ...SK) - (K - 2) * S2 + .....+
所以我们可以想到前缀和来预处理降低时间复杂度。
然后我们滑动窗口求出最小的差异值接得到结果了。
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt(),k=scan.nextInt();
int[] a = new int[n];
for(int i = 0; i<n; i++) {
a[i] = scan.nextInt();
}
Arrays.sort(a);
long[] pre = new long[n+1];
for(int i = 1; i<pre.length; i++) {
pre[i] = pre[i - 1] + a[i - 1];
}
long ans = 0;
for(int i = 1; i<k+1; i++) {
ans += (pre[k] - pre[i]) -(long)(k - i) * a[i - 1];
}
long res = ans;
for(int i = 1; i< n- k + 1; i++) {
ans -= (pre[k + i - 1] - pre[i - 1] - (long)k * a[i - 1]);
ans += (long)(k - 1) * a[i + k - 1];
ans -= (pre[k + i - 1] - pre[i]);
res = Math.min(res, ans);
}
System.out.println(res);
scan.close();
}
}
第五题:花束搭配
问题简述:
给你n列数,每列有2个数,让你 选取两列数 满足条件的方案数:
注意:i列 和 j 列提供两种方案。
条件:两列数为a b
c d 满足 a + b > c + d
问题解答:
思考:
我们看一下这个条件: a + b > c + d; 移一下项
a - c > - (b - d);移一下项
(a - c) + (b -d) > 0;
那也就是,我们只需要枚举每一列的差值c,然后找到满足这个条件的就计数count++;
那样的话就是O(n2)的,c1 + c2 > 0 就行
那我们可以给他们的差值C,排序,使用左右双指针
因为这样的话枚举最大值 j ,我们找到最小的值 i 满足条件,那么中间的都满足条件count += j - i;
枚举最小值 i ,我们找到最大的值 j 满足条件,那么中间的都满足条件count += j - i;
最终的结果为count * 2
代码:
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];
int[] B = new int[n];
for (int i = 0; i < n; i++) {
A[i] = in.nextInt();
}
for (int i = 0; i < n; i++) {
B[i] = in.nextInt();
}
in.close();
long[] delta = new long[n];
for (int i = 0; i < n; i++) {
delta[i] = A[i] - B[i];
}
Arrays.sort(delta);
long count = 0;
int i = 0, j = n - 1;
while (i < j) {
if (delta[i] + delta[j] > 0) {
count += (j - i);
j--;
} else {
i++;
}
}
long ans = count * 2;
System.out.println(ans);
}
}
第六题:妇女唇膏
问题简述:
给你N个数,求出最小正整数b,使得n个数都满足:
a + b = a ^ b
问题解答:
思考:
直接记结论就好了:异或运算相当于无进位加法运算
a + b = a ^ b等价于 a & b = 0;
举个例子:a = 2(10),b = 1(0,1)
则a ^ b = a + b = 3,此时 a & b = 0;
a = 3(11),b = 1(01)
则a ^ b = 2 a +b = 4; 此时 a & b = 0;
我们可以让所以数按位或,求出他们所有在二进制数上的1的位置,然后取反
我们求出最低位的1,即为最小的正整数b,即为结果。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int ans = 0;
for (int i = 0; i < n; i++) {
ans |= scanner.nextInt();
}
System.out.println(~ans & -~ans);
scanner.close();
}
}
上面内容制作不易,喜欢的点个赞和收藏支持一下吧!!
后期会持续更新更多算法内容,如果想跟随共同学习,就点点关注把(