0928携程java岗笔试情况及java代码(AK)
代码等笔试结束后更新~
祝大家顺利~
第一题
题目:判断字符串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); } } } }