修改数组元素使累加和为x的倍数的所有方式

87 阅读1分钟

题目

image.png

  • 假设x=3,除了要修改的元素之外的所有元素累加和%x=2,也就意味着要修改的元素%x=1,这样才能使得最终累加和被x整除
  • 也就意味着1-p能够计算出一个公式,如果1~9,要求%4=1,也就意味着,1-4有一个数满足 1,5-8有一个数满足,4,9自身满足,也就是4个为一组,每组肯定有且仅有一个数满足,然后再求分组后剩余的数有没有满足要求
	public static int ways2(int[] arr, int p, int x) {
		long sum = 0;
                // 先求累加和
		for (int num : arr) {
			sum += num;
		}
		int ans = 0,mod=0;
		for (int num : arr) {
                   // 如果除自身之外的累加和 % 3 = 2,那么目标为 x - 2 = 1
                   // 为了防止累加和 0 时,得出目标为 x 自身的情况,所以还需要 % x 自身 ,使得 mod 也为 0
                   mod=(x-(sum - num) % x)%x
			ans += cnt(p, x, num, mod);
		}
		return ans;
	}

	// 当前数字num
	// 1~p以内,不能是num的情况下,% x == mod的数字有几个
	// O(1)
	public static int cnt(int p, int x, int num, int mod) {
		// p/x 至少有几个
		// (p % x) >= mod ? 1 : 0 剩余部分是否符合要求
          //  mod == 0 ? 1 : 0 当 mod 为 0 时,假设 p =6 ,x =3,那么应该只有 3 和 6 这两个符合要求,用于修正 (p % x) >= mod 多算 1 个的情况
		// 在不考虑变出来的数,是不是num的情况下,算一下有几个数,符合要求
		int ans = (p / x) + ((p % x) >= mod ? 1 : 0) - (mod == 0 ? 1 : 0);
		// 不能等于 num 自身的情况(num必须在p的范围内,且 num % x 为目标需要的数)
		return ans - ((num <= p && num % x == mod) ? 1 : 0);
	}