Joe the Farmer owns a square plot of farmland whose sides are of length N. The land is split into N rows and N columns of equal size, so that there are N2 identical square fields within the farmland. Thanks to the abundant crops that Joe harvested last year, he could afford to buy N sprinklers. They significantly reduce the amount of time that Joe spends watering his plants.
Every sprinkler can be placed in any field of the farmland, but no two sprinklers can occupy the same field. Upon activation, each sprinkler irrigates every field within the same column and row in which it appears.
After delivery, the sprinklers were placed in a batch, so the K-th sprinkler is positioned in field (XK, YK). Joe knows that this arrangement is not optimal, as some fields may not be watered by any sprinkler. Moreover, no column or row should be watered by more than one sprinkler, as it may cause over-hydration of the crops.
In one move, the farmer can move a single sprinkler to an adjacent unoccupied field. Two fields are adjacent to one another if they have a common side.
What is the minimum number of moves required to rearrange the sprinklers so that all fields will be irrigated by sprinklers, and no two sprinklers will water the same column or row? Since the answer can be very large, provide it modulo 1,000,000,007 (109 + 7).
Write a function:
class Solution { public int solution(int[] X, int[] Y); }
that, given arrays X and Y, both consisting of N integers and representing the coordinates of consecutive sprinklers, returns a minimal number of moves modulo 1,000,000,007, required to irrigate all fields.
For example, given array X = [1, 2, 2, 3, 4] and array Y = [1, 1, 4, 5, 4] the function should return 5, as we can make following moves:
For another example, given array X = [1, 1, 1, 1] and array Y = [1, 2, 3, 4] the function should return 6:
Given array X = [1, 1, 2] and array Y = [1, 2, 1] the function should return 4:
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [2..100,000];
- each element of arrays X and Y is an integer within the range [1..N];
- each sprinkler appears in a distinct field (no field may contain more than one sprinkler).
using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(int[] X, int[] Y) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 0) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
}
}
total = GetModuloValue(total);
}
if(missingIndexes.Count > 0)
{
Console.WriteLine("Calculation not correct. Missing indexes count " + missingIndexes.Count);
}
if(extraIndexes.Count > 0)
{
Console.WriteLine("Calculation not correct. Excta Indexes Count " + extraIndexes.Count);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
// there are still sprinkles that can be used
if (count > 1)
{
var newEntry = new KeyValuePair<int, int>(i, count);
extraIndexes.Push(newEntry);
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
// there are still sprinkles that can be used
if (count > 1)
{
var newEntry = new KeyValuePair<int, int>(i, count);
extraIndexes.Push(newEntry);
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
using System;
using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
private const ulong ModuloValue = 1000000007;
public ulong GetModuloValue(ulong u)
{
return u % ModuloValue;
}
public int GetTotalByAxis(int[] X)
{
var map = new Dictionary<int, int>(X.Length);
ulong total = 0;
// fill the map with the positions
for (int i = 0; i < X.Length; i++)
{
var val = X[i] - 1;
if(!map.ContainsKey(val))
{
map.Add(val, 0);
}
map[val]++;
}
var missingIndexes = new Queue<int>();
// pair index and sprinkles
var extraIndexes = new Stack<KeyValuePair<int, int>>();
var currentExtra = 0;
for (int i = 0; i < X.Length; i++)
{
if (!map.ContainsKey(i))
{
if(extraIndexes.Count > 0)
{
var extraIndex = extraIndexes.Pop();
total += GetModuloValue((ulong)(i - extraIndex.Key));
var newEntry = new KeyValuePair<int, int>(extraIndex.Key, extraIndex.Value-1);
if(newEntry.Value > 1)
{
extraIndexes.Push(newEntry);
}
}
else
{
missingIndexes.Enqueue(i);
}
}
else
{
// no missing indexed
if(missingIndexes.Count == 0 && map[i] > 1)
{
var newEntry = new KeyValuePair<int, int>(i, map[i]);
extraIndexes.Push(newEntry);
}
else if (missingIndexes.Count > 0 && map[i] > 1) //there are missing indexes, fill them from this
{
var count = map[i];
while (count > 1 && missingIndexes.Count > 0)
{
var missinigIndex = missingIndexes.Dequeue();
total += GetModuloValue((ulong)(i - missinigIndex));
count--;
}
// there are still sprinkles that can be used
if (count > 1)
{
var newEntry = new KeyValuePair<int, int>(i, count);
extraIndexes.Push(newEntry);
}
}
}
total = GetModuloValue(total);
}
return Convert.ToInt32(GetModuloValue(total));
}
public int solution(int[] X, int[] Y) {
var total = 0;
total += GetTotalByAxis(X);
total += GetTotalByAxis(Y);
return total;
}
}
The solution obtained perfect score.
Test with one sprinkler in the corner and all the others very close to diagonal
All sprinklers are gathered in left upper corner / right lower corner