-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathACPC11B.cs
109 lines (100 loc) · 4.12 KB
/
ACPC11B.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Text;
// https://www.spoj.com/problems/ACPC11B/ #binary-search #merge #sorting
// Finds the closest pair of altitudes, one from each of two mountains.
public static class ACPC11B
{
// Knowing where an altitude on one mountain goes relative to the sort of the other mountain's
// altitudes effectively tells us the closest altitudes (the ones to its left and right).
// One option is to sort both and then perform a merge basically, but it's only necessary
// to sort one and traverse the second while binary searching on the first. So it'll be
// O(nlogn) + O(mlogn) ~ O((n + m)logn) sorting/binary searching on the n, the n + m
// is commutative so might as well minimize the logn term by sorting the smallest array.
public static int Solve(int[] firstAltitudes, int[] secondAltitudes)
{
int[] sortedAltitudes;
int[] unsortedAltitudes;
if (firstAltitudes.Length < secondAltitudes.Length)
{
Array.Sort(firstAltitudes);
sortedAltitudes = firstAltitudes;
unsortedAltitudes = secondAltitudes;
}
else
{
Array.Sort(secondAltitudes);
sortedAltitudes = secondAltitudes;
unsortedAltitudes = firstAltitudes;
}
int minimumDifference = int.MaxValue;
for (int a = 0; a < unsortedAltitudes.Length; ++a)
{
int altitude = unsortedAltitudes[a];
int index = Array.BinarySearch(sortedAltitudes, altitude);
if (index >= 0)
{
// The altitude for this mountain is also an altitude for the other mountain.
return 0;
}
else
{
// The altitude for this mountain isn't one on the other mountain, but the bitwise
// complement of what's returned by binary search tells us the index of the first altitude
// that's greater than this one, (or falls off the end of the array if bigger than all).
index = ~index;
if (index == 0)
{
// Altitude is less than all altitudes on the other mountain.
minimumDifference = Math.Min(
minimumDifference,
sortedAltitudes[0] - altitude);
}
else if (index < sortedAltitudes.Length)
{
// Altitude is between two altitudes on the other mountain.
minimumDifference = Math.Min(
minimumDifference,
altitude - sortedAltitudes[index - 1]);
minimumDifference = Math.Min(
minimumDifference,
sortedAltitudes[index] - altitude);
}
else
{
// Altitude is greater than all altitudes on the other mountain.
minimumDifference = Math.Min(
minimumDifference,
altitude - sortedAltitudes[sortedAltitudes.Length - 1]);
}
}
}
return minimumDifference;
}
}
public static class Program
{
private static void Main()
{
var output = new StringBuilder();
int remainingTestCases = int.Parse(Console.ReadLine());
while (remainingTestCases-- > 0)
{
string[] firstLine = Console.ReadLine().Split();
string[] secondLine = Console.ReadLine().Split();
int[] firstAltitudes = new int[firstLine.Length - 1];
for (int a = 0; a < firstLine.Length - 1; ++a)
{
firstAltitudes[a] = int.Parse(firstLine[a + 1]);
}
int[] secondAltitudes = new int[secondLine.Length - 1];
for (int a = 0; a < secondLine.Length - 1; ++a)
{
secondAltitudes[a] = int.Parse(secondLine[a + 1]);
}
output.Append(
ACPC11B.Solve(firstAltitudes, secondAltitudes));
output.AppendLine();
}
Console.Write(output);
}
}