生成一个矩阵,每行的每个子数组的平均值为整数
给定两个整数M和N ,任务是生成一个MxN矩阵,其元素在[1, MxN]范围内,使得任何行的任何子数组的平均值都是整数。如果不能这样做,则返回 -1。
例子:
Input: M = 2, N = 3
Output:
1 3 5
2 4 6
Explanation: Subarrays of first row with size greater than 1 are {1, 3}, {3, 5}, {1, 3, 5}. Means are 2, 4 and 3 respectively.
Subarrays of 2nd row are with size greater than 1 are {2, 4}, {4, 6}, {2, 4, 6}. Means are 3, 5 and 4 respectively.
Input: M = 1, N = 3
Output: -1
Explanation: All Possible arrangements are: {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}.
In every arrangements there is a subarray whose mean is a decimal value and not an integer.
方法:该方法的解决方案基于以下数学观察:
- 子数组的大小必须完全除以元素的总和,才能使平均值成为整数值。
- 元素是从1 到 M*N的自然数。
- 前 'n' 个奇数之和等于n 2 ,前 'n' 个偶数之和等于n(n+1) 。
现在假设我们从第一个n奇数元素中丢弃第一个k奇数元素,然后将其余元素视为子数组:
Total numbers = n
Numbers discarded = k
Numbers in subarray = n – k
Sum of 1st n numbers =n2
Sum of 1st k numbers =k2
Therefore, sum of subarray = n2 – k2
=> mean = (n2 – k2)/(n – k)
= (n + k)*(n – k)/(n – k)
= (n + k), which is an integer as both n and k are integers
类似地,假设从第一个n 个偶数元素中,丢弃第一个k个偶数元素并将其余元素视为子数组,然后:
Total numbers = n
Numbers discarded = k
Numbers in subarray = n – k
Sum of 1st n numbers =n(n + 1)
Sum of 1st k numbers =k(k + 1)
Therefore, sum of subarray = n(n + 1) – k(k + 1)
=> mean = (n(n + 1) – k(k + 1))/(n – k)
= (n2 + n – k2 – k)/(n-k)
= (n2 – k2)/(n – k) + (n-k)/(n-k)
= (n + k)*(n – k)/(n – k) + 1
= (n + k) + 1, which is an integer as both n and k are integers.
按照下面提到的步骤来实现上述观察:
- 从上面的观察来看,以这样一种方式排列,每一行要么全是偶数,要么全是奇数。
- 检查奇数和偶数是否相等,并且 MxN 必须是偶数。
- 如果行数是奇数,则不可能进行有效的排列,因为奇数和偶数元素不能保持在一起。总会有至少一行同时包含奇数和偶数元素。
下面是上述方法的实现。
C++
// C++ code to implement the above approach
#include
using namespace std;
void validArrangement(int M, int N)
{
// If N == 1 then the only
// subarray possible is of length 1
// therefore, the mean will
// always be an integer
if (N == 1) {
for (int i = 1; i <= M; i++)
cout << i << endl;
return;
}
// If M is odd the valid
// arrangement is not possible
if (M % 2 == 1) {
cout << -1 << endl;
return;
}
// Else print all the rows
// such that all elements of each row
// is either odd or even
else {
// Count for the rows
for (int i = 1; i <= M; i++) {
// Initialize num with i
int num = i;
// Count for the columns
for (int j = 1; j <= N; j++) {
cout << num << " ";
// As M is even,
// even + even will give even
// whereas odd + even gives odd
num += M;
}
cout << endl;
}
return;
}
}
// Driver Code
int main()
{
int M = 2, N = 3;
// Function call
validArrangement(M, N);
return 0;
}
Java
// JAVA code to implement the above approach
import java.util.*;
class GFG {
public static void validArrangement(int M, int N)
{
// If N == 1 then the only
// subarray possible is of length 1
// therefore, the mean will
// always be an integer
if (N == 1) {
for (int i = 1; i <= M; i++)
System.out.println(i);
return;
}
// If M is odd the valid
// arrangement is not possible
if (M % 2 == 1) {
System.out.println(-1);
return;
}
// Else print all the rows
// such that all elements of each row
// is either odd or even
else {
// Count for the rows
for (int i = 1; i <= M; i++) {
// Initialize num with i
int num = i;
// Count for the columns
for (int j = 1; j <= N; j++) {
System.out.print(num + " ");
// As M is even,
// even + even will give even
// whereas odd + even gives odd
num += M;
}
System.out.println();
}
return;
}
}
// Driver Code
public static void main(String[] args)
{
int M = 2, N = 3;
// Function call
validArrangement(M, N);
}
}
// This code is contributed by Taranpreet
Python3
# Python3 code to implement the above approach
def validArrangement(M, N):
# If N == 1 then the only
# subarray possible is of length 1
# therefore, the mean will
# always be an integer
if (N == 1):
for i in range(1, M + 1):
print(i)
return
# If M is odd the valid
# arrangement is not possible
if (M % 2 == 1):
print(i)
return
# Else print all the rows
# such that all elements of each row
# is either odd or even
else :
# Count for the rows
for i in range(1,M+1):
# Initialize num with i
num = i
# Count for the columns
for j in range(1,N+1):
print(num,end=" ")
# As M is even,
# even + even will give even
# whereas odd + even gives odd
num += M
print("")
return
# Driver Code
M = 2
N = 3
# Function call
validArrangement(M, N)
# This code is contributed by shinjanpatra
C#
// C# code to implement the above approach
using System;
public class GFG
{
public static void validArrangement(int M, int N)
{
// If N == 1 then the only
// subarray possible is of length 1
// therefore, the mean will
// always be an integer
if (N == 1) {
for (int i = 1; i <= M; i++)
Console.WriteLine(i);
return;
}
// If M is odd the valid
// arrangement is not possible
if (M % 2 == 1) {
Console.WriteLine(-1);
return;
}
// Else print all the rows
// such that all elements of each row
// is either odd or even
else {
// Count for the rows
for (int i = 1; i <= M; i++) {
// Initialize num with i
int num = i;
// Count for the columns
for (int j = 1; j <= N; j++) {
Console.Write(num + " ");
// As M is even,
// even + even will give even
// whereas odd + even gives odd
num += M;
}
Console.WriteLine();
}
return;
}
}
// Driver Code
public static void Main(String[] args) {
int M = 2, N = 3;
// Function call
validArrangement(M, N);
}
}
// This code is contributed by shikhasingrajput
Javascript
1 3 5
2 4 6
时间复杂度: O(MxN)
辅助空间: O(1)