给定两个整数N和M。在每个操作中,选择大小为N * M的2D网格的K个像元并进行排列。如果我们选择K个像元(x 1 ,y 1 ),(x 2 ,y 2 ),…和(x K ,y K ),则这种安排的成本计算为∑ i = 1 K-1 ∑ j = i + 1 K (| x i – x j | + | y i – y j |) 。任务是找到单元所有可能布置的成本总和。答案可能非常大,因此请以10 9 + 7的模数打印答案
例子:
Input: N = 2, M = 2, K = 2
Output: 8
((1, 1), (1, 2)), with the cost |1-1| + |1-2| = 1
((1, 1), (2, 1)), with the cost |1-2| + |1-1| = 1
((1, 1), (2, 2)), with the cost |1-2| + |1-2| = 2
((1, 2), (2, 1)), with the cost |1-2| + |2-1| = 2
((1, 2), (2, 2)), with the cost |1-2| + |2-2| = 1
((2, 1), (2, 2)), with the cost |2-2| + |1-2| = 1
Input: N = 4, M = 5, N = 4
Output: 87210
方法:问题是在从NM个单元中选择K个单元时找到曼哈顿距离的总和。由于表达显然是独立的X和Y的,发现X的差和Y之差的绝对值的分别的总和的绝对值的总和。考虑X的差异。当固定2个正方形的特定组合时,由于从这些中选择K – 2个单元格时,这些差异每次都会贡献1度,因此可以固定该对N * M – 2 C K – 2 。此外,由于如果X相同,则差为0 ,因此假设X不同,则可以选择2个平方,以使X的差的绝对值为d((N – d)* M 2 ) 。如果将其加到所有d中,您将得到有关X的答案。至于Y , N和M可以互换地解决,这个问题可以在O(N * M)中解决。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define N 100005
#define mod (int)(1e9 + 7)
// To store the factorials and factorial
// mod inverse of the numbers
int factorial[N], modinverse[N];
// Function to return (a ^ m1) % mod
int power(int a, int m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (1LL * a * a) % mod;
else if (m1 & 1)
return (1LL * a
* power(power(a, m1 / 2), 2))
% mod;
else
return power(power(a, m1 / 2), 2) % mod;
}
// Function to find the factorials
// of all the numbers
void factorialfun()
{
factorial[0] = 1;
for (int i = 1; i < N; i++)
factorial[i] = (1LL * factorial[i - 1]
* i)
% mod;
}
// Function to find factorial mod
// inverse of all the numbers
void modinversefun()
{
modinverse[N - 1]
= power(factorial[N - 1], mod - 2) % mod;
for (int i = N - 2; i >= 0; i--)
modinverse[i] = (1LL * modinverse[i + 1]
* (i + 1))
% mod;
}
// Function to return nCr
int binomial(int n, int r)
{
if (r > n)
return 0;
int a = (1LL * factorial[n]
* modinverse[n - r])
% mod;
a = (1LL * a * modinverse[r]) % mod;
return a;
}
// Function to return the sum of the costs of
// all the possible arrangements of the cells
int arrange(int n, int m, int k)
{
factorialfun();
modinversefun();
long long ans = 0;
// For all possible X's
for (int i = 1; i < n; i++)
ans += (1LL * i * (n - i) * m * m) % mod;
// For all possible Y's
for (int i = 1; i < m; i++)
ans += (1LL * i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2, k - 2)) % mod;
return (int)ans;
}
// Driver code
int main()
{
int n = 2, m = 2, k = 2;
cout << arrange(n, m, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
static int N = 20;
static int mod = 1000000007;
// To store the factorials and factorial
// mod inverse of the numbers
static int []factorial = new int[N];
static int []modinverse = new int[N];
// Function to return (a ^ m1) % mod
static int power(int a, int m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (a * a) % mod;
else if ((m1 & 1) != 0)
return (a * power(power(a, m1 / 2), 2)) % mod;
else
return power(power(a, m1 / 2), 2) % mod;
}
// Function to find the factorials
// of all the numbers
static void factorialfun()
{
factorial[0] = 1;
for (int i = 1; i < N; i++)
factorial[i] = (factorial[i - 1] * i) % mod;
}
// Function to find factorial mod
// inverse of all the numbers
static void modinversefun()
{
modinverse[N - 1] = power(factorial[N - 1],
mod - 2) % mod;
for (int i = N - 2; i >= 0; i--)
modinverse[i] = (modinverse[i + 1] *
(i + 1)) % mod;
}
// Function to return nCr
static int binomial(int n, int r)
{
if (r > n)
return 0;
int a = (factorial[n] *
modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
}
// Function to return the sum of the costs of
// all the possible arrangements of the cells
static int arrange(int n, int m, int k)
{
factorialfun();
modinversefun();
int ans = 0;
// For all possible X's
for (int i = 1; i < n; i++)
ans += (i * (n - i) * m * m) % mod;
// For all possible Y's
ans = 8;
for (int i = 1; i < m; i++)
ans += (i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2,
k - 2)) % mod + 8;
return ans;
}
// Driver code
public static void main(String []args)
{
int n = 2, m = 2, k = 2;
System.out.println(arrange(n, m, k));
}
}
// This code is contributed by Surendra_Gangwar
Python3
# Python3 implementation of the approach
N = 100005
mod = (int)(1e9 + 7)
# To store the factorials and factorial
# mod inverse of the numbers
factorial = [0] * N;
modinverse = [0] * N;
# Function to return (a ^ m1) % mod
def power(a, m1) :
if (m1 == 0) :
return 1;
elif (m1 == 1) :
return a;
elif (m1 == 2) :
return (a * a) % mod;
elif (m1 & 1) :
return (a * power(power(a, m1 // 2), 2)) % mod;
else :
return power(power(a, m1 // 2), 2) % mod;
# Function to find the factorials
# of all the numbers
def factorialfun() :
factorial[0] = 1;
for i in range(1, N) :
factorial[i] = (factorial[i - 1] * i) % mod;
# Function to find factorial mod
# inverse of all the numbers
def modinversefun() :
modinverse[N - 1] = power(factorial[N - 1],
mod - 2) % mod;
for i in range(N - 2 , -1, -1) :
modinverse[i] = (modinverse[i + 1] *
(i + 1)) % mod;
# Function to return nCr
def binomial(n, r) :
if (r > n) :
return 0;
a = (factorial[n] * modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
# Function to return the sum of the costs of
# all the possible arrangements of the cells
def arrange(n, m, k) :
factorialfun();
modinversefun();
ans = 0;
# For all possible X's
for i in range(1, n) :
ans += ( i * (n - i) * m * m) % mod;
# For all possible Y's
for i in range(1, m) :
ans += ( i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2, k - 2)) % mod;
return int(ans);
# Driver code
if __name__ == "__main__" :
n = 2; m = 2; k = 2;
print(arrange(n, m, k));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
static int N = 20;
static int mod = 1000000007;
// To store the factorials and factorial
// mod inverse of the numbers
static int []factorial = new int[N];
static int []modinverse = new int[N];
// Function to return (a ^ m1) % mod
static int power(int a, int m1)
{
if (m1 == 0)
return 1;
else if (m1 == 1)
return a;
else if (m1 == 2)
return (a * a) % mod;
else if ((m1 & 1) != 0)
return (a * power(power(
a, m1 / 2), 2)) % mod;
else
return power(power(a, m1 / 2), 2) % mod;
}
// Function to find the factorials
// of all the numbers
static void factorialfun()
{
factorial[0] = 1;
for (int i = 1; i < N; i++)
factorial[i] = (factorial[i - 1] * i) % mod;
}
// Function to find factorial mod
// inverse of all the numbers
static void modinversefun()
{
modinverse[N - 1] = power(factorial[N - 1],
mod - 2) % mod;
for (int i = N - 2; i >= 0; i--)
modinverse[i] = (modinverse[i + 1] *
(i + 1)) % mod;
}
// Function to return nCr
static int binomial(int n, int r)
{
if (r > n)
return 0;
int a = (factorial[n] *
modinverse[n - r]) % mod;
a = (a * modinverse[r]) % mod;
return a;
}
// Function to return the sum of the costs of
// all the possible arrangements of the cells
static int arrange(int n, int m, int k)
{
factorialfun();
modinversefun();
int ans = 0;
// For all possible X's
for (int i = 1; i < n; i++)
ans += (i * (n - i) * m * m) % mod;
// For all possible Y's
ans = 8;
for (int i = 1; i < m; i++)
ans += (i * (m - i) * n * n) % mod;
ans = (ans * binomial(n * m - 2,
k - 2)) % mod + 8;
return ans;
}
// Driver code
public static void Main(String []args)
{
int n = 2, m = 2, k = 2;
Console.WriteLine(arrange(n, m, k));
}
}
// This code is contributed by PrinciRaj1992
8