网易2017春招[编程题]魔力手环

xiaoxiao2021-02-28  45

链接:https://www.nowcoder.com/questionTerminal/79c639e02bc94e6b919e3372c8e1dc5e 来源:牛客网

时间限制:1秒空间限制:32768K算法知识视频讲解 小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。
输入描述:
输入数据包括两行: 第一行为两个整数n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔 第二行为魔力手环初始的n个数,以空格分隔。范围都在0至99.
输出描述:
输出魔力手环使用k次之后的状态,以空格分隔,行末无空格。 示例1

输入

3 2 1 2 3

输出

8 9 7

package go.jacob.day913; import java.util.Scanner; /** * [编程题]魔力手环 * * @author Jacob 利用矩阵快速幂求解 */ public class Demo5 { /* * 思路参考:@minnnng 如输入A = [[1, 2, 3]], k = 2。 * 我们可以构造一个这样的矩阵B(代码中的mul矩阵)[[1, 0, * 1], [1, 1, 0], [0, 1, 1]], 使得A*Bk相当于A转换k次后的样子。 * 所以原问题就变成求矩阵快速幂。快速幂取余中,a k * % c =  (a % c)k % c。 类似问题:O(log(n))复杂度的Fibonacci数列, * */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), k = sc.nextInt(); // 将arr表示成矩阵而不是数组,是为了方便后续计算 int[][] arr = new int[n][n]; for (int i = 0; i < n; i++) { arr[0][i] = sc.nextInt(); } // 构造矩阵 int[][] mat = new int[n][n]; for (int i = 0; i < n; i++) { mat[i][i] = 1; // 取模 mat[(i + 1) % n][i] = 1; } // 模拟矩阵运算 for (; k > 0; k >>= 1) { //说明最后一位为1,进行右移时会丢失精度 if ((k & 1) == 1) arr = solve(arr, mat); mat = solve(mat, mat); } System.out.print(arr[0][0]); for(int i=1;i<arr.length;i++) System.out.print(" "+arr[0][i]); } // 矩阵相乘 private static int[][] solve(int[][] mat1, int[][] mat2) { int n = mat1.length; int[][] res = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { if (mat1[i][k] == 0 || mat2[k][j] == 0) continue; res[i][j] += mat1[i][k] * mat2[k][j]; } if(res[i][j]>=100) res[i][j]%=100; } } return res; } }

转载请注明原文地址: https://www.6miu.com/read-600052.html

最新回复(0)