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

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

小易拥有一个拥有魔力的手环上面有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;

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值