代码等笔试结束后更新~
祝大家顺利~
第一题
题目:判断字符串str1能否通过交换一次不同位置的两个字符编程str2。
思路:暴力模拟。
代码:
import java.util.*;
/*
3
abc acb
goto goto
arc abc
Yes
Yes
No
*/
public class Q1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
for (int i = 0; i < n; i++) {
String str = sc.nextLine();
String[] strs = str.split(" ");
if(func(strs[0],strs[1])) {
System.out.println("Yes");
}
else{
System.out.println("No");
}
}
}
public static boolean func(String str1, String str2) {
// System.out.println("str1:"+str1+"\nstr2:"+str2);
if(str1.length() != str2.length()) {
return false;
}
HashMap<Character,Integer> cnt1 = new HashMap<>();
char str1ch = 'a',str2ch = 'a';
int difCnt = 0;
boolean flag = false;
for (int i = 0; i < str1.length(); i++) {
cnt1.put(str1.charAt(i),cnt1.getOrDefault(str1.charAt(i),0)+1);
if(cnt1.get(str1.charAt(i))>=2) flag = true;
// System.out.println("\t"+i+"\tch:("+str1.charAt(i)+","+str2.charAt(i)+")");
if(str1.charAt(i)!=str2.charAt(i)) {
if(difCnt == 0) {
str1ch = str1.charAt(i);
str2ch = str2.charAt(i);
difCnt++;
// System.out.println("\t\tstr1ch:"+str1ch+"\tstr2ch:"+str2ch+"\tdifCnt:"+difCnt);
}
else if(difCnt == 1) {
// System.out.println("\t\tstr1ch:"+str1ch+"\tstr2ch:"+str2ch+"\tdifCnt:"+difCnt);
if(str1.charAt(i)!=str2ch || str1ch != str2.charAt(i)) {
return false;
}
difCnt++;
}
else {
return false;
}
}
}
if(difCnt == 0) {
if(flag) return true;
return false;
}
return difCnt==2;
}
}
第二题
题目:一个仅由233,2330,233X10^k的数相加而得的数称为233数,给一个数n(n<=10^14),判断n是否是一个233数,如果不是输出-1,如果是,则输出构成n最少的233数个数。
思路:由233数的定义可知,233数求余233必须为0,否则输出-1。然后构造一个数组,里面的元素分别为233x10^12, 233x10^11, .... , 233x10^1, 233;然后从大到小判断n是否大于当前数a[i],如果大于,则ans+=(n/a[i]),然后更新ans为ans%a[i],即可
代码
import java.util.Scanner;
/*
4
232
233
466
23300
-1
1
2
1
*/
public class Q2{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long arr[] = new long[14];
arr[0] = 233;
for (int i = 1; i < arr.length; i++) {
arr[i] = arr[i-1] * 10;
}
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
long x = sc.nextLong();
int ans = 0;
if(x%233 != 0) {
System.out.println(-1);
continue;
}
else {
for (int j = arr.length-1; j >= 0; j--) {
if(x < arr[j]) {
continue;
}
ans += x/arr[j];
x = x%arr[j];
}
}
System.out.println(ans);
}
}
}
第三题
题目大意:给一个数组,考虑将其中的最多k个数剔除数组,并加入这k个数的平均值,问数组中最大值和最小值的差最小能为多少?
思路:先将数组排序,然后/分别考虑从左边剔除i(0<=i<=k)个元素,右边剔除k-i个元素的情况下,保存数组最大值和最小值差距的最小值。(平均值通过前缀和数组求)
代码
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
/*
4 2
5 4 2 4
0.5
4 4
5 4 2 4
0
*/
public class Q3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
if (n <= k) {
System.out.println(0);
return;
}
double arr[] = new double[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextDouble();
}
Arrays.sort(arr);
double leftSum[] = new double[k + 1];
double rightSum[] = new double[k + 1];
for (int i = 1; i <= k; i++) {
leftSum[i] = leftSum[i - 1] + arr[i - 1];
}
for (int i = n - 1; i >= n - k; i--) {
rightSum[n - i] = rightSum[n - i - 1] + arr[i];
}
double ans = arr[n - 1] - arr[0];
for (int i = 0; i <= k; i++) {
int j = k - i;
double avg = (leftSum[i] + rightSum[j]) / (i + j);
double max = Math.max(arr[n - 1 - j], avg);
double min = Math.min(arr[i], avg);
ans = Math.min(ans, max - min);
}
System.out.println(ans);
}
}
第四题
题目大意:k-好数组(定义:任何一个长度为k的连续数组和都相同)给了t个样例,每个样例给出数组长度n,连续子数组的长度k,以及可增加的次数x。问能不能把给出的数组变成一个k-好数组,每次可以把数组中的一个元素+1,最多可以增x次。
思路:由于任意两个长度为k的数组和都必须相同,可以推出x(i) + x(i+1) + .... + x(i+k-1) = x(i+1) + ... + x(i+k-1) + x(i+k) 可以推出 x(i) = x(i+k),因此可以先将数组中的元素分为k组,然后记录每组的元素个数和最大值,因为每组中的所有元素最终都要相同,所以对于下标为j(0<j<n)的元素,其最少需要增加max[j%k]-arr[j]次。先判断总的需要加的次数,如果大于x,则返回-1。否则更新x为x'(减去需要加的数量),然后求增加后的最大值,即对每组的元素,求max[i] + ( x'/cnt[i])的最大值即可。
代码
import java.util.Scanner;
/*
3
4 3 1
1 2 1 1
4 2 5
1 2 3 4
5 3 1
1 100 1 1 1
3
4
-1
*/
public class Q4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
int n = sc.nextInt();
int k = sc.nextInt();
int x = sc.nextInt();
int arr[] = new int[n];
//arr[i]和arr[i+k]必须相等
//因此分成k组
int max[] = new int[k];
int cnt[] = new int[k];
for (int j = 0; j < n; j++) {
arr[j] = sc.nextInt();
max[j%k] = Math.max(arr[j],max[j%k]);
cnt[j%k]++;
}
int needAdd = 0;
for (int j = 0; j < n; j++) {
needAdd += max[j%k]-arr[j];
}
if(needAdd > x) {
System.out.println(-1);
}
else {
x-=needAdd;
int ans = 0;
for (int j = 0; j < k; j++) {
ans = Math.max(ans,max[j]+x/cnt[j]);
}
System.out.println(ans);
}
}
}
}
#携程笔试##携程##2023一起秋招吧##23届秋招笔面经#