250323拼多多后端暑期笔试
贴个Java代码
计算最终位置
模拟即可
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextInt()) { // 注意 while 处理多个 case int t = in.nextInt(); while (t-- > 0) { int x = in.nextInt(), y = in.nextInt(); String s = in.next(); for (char c : s.toCharArray()) { if (c == 'W') y++; else if (c == 'A') x--; else if (c == 'S') y--; else x++; } System.out.println(x == 0 && y == 0 ? "YES" : "NO"); } } } }
计算区间内幸运数字的个数
如果一个数字的子串数字可以被3整除,那么就是幸运数字
其实只要计算小于100的非法数,因为3位数以及更多位数一定是幸运数字
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 // [8, 19]: 9 10 12 13 15 16 18 19 // 非法的数要么全是mod1组成,要么全是mod2组成,比如11 14 17 22 25 28 // 111也不行,个数还必须不能>=3,所以3位数xxx一定是幸运数字,比如11x一定是幸运数字 while (in.hasNextInt()) { // 注意 while 处理多个 case int t = in.nextInt(); int[] valid = new int[100]; for (int i = 1; i < 100; i++) { // 判断[1, 99]的数字是否幸运 int x = i, pre = -1; while (x > 0) { int cur = x % 10; if (cur % 3 == 0) valid[i] = 1; // 如果当前位,模三等于0,那么就是幸运 if (pre == -1) pre = cur % 3; else if (cur % 3 != pre) valid[i] = 1; // 如果当前位模三 不等于 之前位模三,那么这两个位连起来就是幸运数字 x /= 10; } } // System.out.println(Arrays.toString(valid)); int[] sum = new int[100]; for (int i = 1; i < 100; i++) { // 统计前缀和 sum[i] = sum[i-1] + valid[i]; } while (t-- > 0) { long l = in.nextLong(), r = in.nextLong(); long res = 0; if (l >= 100) { // 如果L大于等于100,那么区间内肯定都是幸运数字 res = r - l + 1; } else { if (r >= 100) { // 如果L小于100,R大于等于100,那么给右边界缩小到99,然后用前缀和计算100以内的幸运数字个数 res += r - 99; r = 99; } res += sum[(int)r] - sum[(int)(l-1)]; } System.out.println(res); } } } }
计算可以看到右边的人的个数之和
可以用单调栈来获得每个元素的后上界
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextInt()) { // 注意 while 处理多个 case int n = in.nextInt(); long[] nums = new long[n]; for (int i = 0; i < n; i++) nums[i] = in.nextLong(); long res = 0; Deque<Integer> stack = new LinkedList<>(); for (int i = 0; i < n; i++) { while(!stack.isEmpty() && nums[stack.peek()] <= nums[i]) { // 递增栈 res += i - stack.pop(); } stack.push(i); } while (!stack.isEmpty()) { // 剩下的元素都可以看到右边所有人 res += n-1 - stack.pop(); } System.out.println(res); } } }
计算按照索引替换字符后的最小字典序字符串
主要是理解题意,给字符串b排序,然后贪心替换字符串a的对应索引字符
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 // 对于字符串a,有些字符会被替换不止一次,有些字符可能一次都不会被替换 // 我们只需要考虑被替换字符的最小字典序 while (in.hasNextInt()) { // 注意 while 处理多个 case int t = in.nextInt(); while (t-- > 0) { int n = in.nextInt(), m = in.nextInt(); String a = in.next(), b = in.next(); int[] nums = new int[m]; for (int i = 0; i < m; i++) nums[i] = in.nextInt(); TreeSet<Integer> set = new TreeSet<>(); // 用TreeSet保存可以替换的索引,相当于去重并排序 for (int x : nums) set.add(x); char[] cs = b.toCharArray(); Arrays.sort(cs); char[] res = a.toCharArray(); int idx = 0; for (int key : set) { // 贪心替换字符串a res[key-1] = cs[idx++]; } System.out.println(String.valueOf(res)); } } } }