阿里3.23笔试
第一题,快速幂实现版本,笔试的时候没写出来,不知道是否能AC,欢迎大佬来喷!
题目:现有n个人,要从n个人里选择任意数量的人组成一个队伍,再在选择出的人中选择一个队长,如果两个方案选取的人的集合不同或队长不同,认为是不同的方案,求不同的方案数对1000000007取模的结果。
1 <= n <= 1000000000
import java.util.Scanner; public class Main { static int mod = 1000000007; public static void main(String[] args) { Scanner reader = new Scanner(System.in); int n = reader.nextInt(); // 结果等于 n * 2 ^ (n - 1) System.out.println((n * powSelf(2, n - 1)) % mod); } // 快速幂的实现 public static long powSelf(int x, int n) { // n >= 0 if (n == 0) { return 1; } long res = 1; long temp = x % mod; while (n > 0) { if ((n & 1) == 1) { res = (res * temp) % mod; } n >>= 1; temp = (temp * temp) % mod; } return res; } }
附上网上找的取模运算性质链接https://blog.csdn.net/Mtrix/article/details/47087647
第二题代码,也是看了大佬的之后才写的,发出来让大家检查,也方便之后自己复习。
import java.util.LinkedList; import java.util.Scanner; public class Main2 { static int [][] forward = new int[][]{{-1,0},{1,0},{0,1},{0,-1}}; static class Node{ int node_x; int node_y; Node(int x, int y){ node_x = x; node_y = y; } } // 使用广度优先搜索的方法 public static void main(String[] args){ Scanner reader = new Scanner(System.in); int n = reader.nextInt(); int m = reader.nextInt(); reader.nextLine(); char[][] strChar = new char[n][m]; int end_x = -1; int end_y = -1; LinkedList<Node> queue = new LinkedList<>(); int[][][] dp = new int[n][m][6]; // 代dp[i][j][k]代表到达[i][j]位置,用了k个飞行器时(不一定要都用,是有k个飞行器的条件),最少经过的步数 // 给dp中的每个值附一个初值 for(int i = 0; i < n;i++){ for(int j = 0; j < m;j++){ for(int k = 0; k < 6;k++){ dp[i][j][k] = m * n + 1; // 注意,不可以赋值为Integer.MAX_VALUE,加减之后会出现负值 } } } for(int i = 0; i < n; i++){ String temp = reader.nextLine(); for(int j = 0; j < m;j++){ if(temp.charAt(j) == 'S'){ Node node = new Node(i,j); for(int k = 0; k < 6;k++){ dp[i][j][k] = 0; } queue.add(node); } else if(temp.charAt(j) == 'E'){ end_x = i; end_y = j; } strChar[i][j] = temp.charAt(j); } } // 广度优先搜索,寻找到达终点经过的最少的步数 while(!queue.isEmpty()){ Node node = queue.poll(); int x = node.node_x; int y = node.node_y; // 上下左右走,相同k更新 for(int i = 0; i < 4;i++){ int temp_x = x + forward[i][0]; int temp_y = y + forward[i][1]; if(temp_x >= 0 && temp_x < n && temp_y >= 0 && temp_y < m && strChar[temp_x][temp_y] != '#'){ boolean flag = false; for(int k = 0; k < 6;k++){ if(dp[temp_x][temp_y][k] > dp[x][y][k] + 1){ dp[temp_x][temp_y][k] = dp[x][y][k] + 1; flag = true; } } // 相当于每一个节点的步数重新做了更新,都要重新考虑一遍此节点 if(flag){ queue.add(new Node(temp_x,temp_y)); } } } // 跳跃更新 if(strChar[n - x - 1][m - y - 1] != '#'){ boolean flag = false; for(int k = 0; k < 5; k++){ if(dp[n - x - 1][m - y - 1][k + 1] > dp[x][y][k] + 1){ dp[n - x - 1][m - y - 1][k + 1] = dp[x][y][k] + 1; flag = true; } } if(flag){ queue.add(new Node(n - x - 1,n - y - 1)); } } } if(dp[end_x][end_y][5] != n * m + 1) { System.out.println(dp[end_x][end_y][5]); } else{ System.out.println(-1); } } }