using
System;
using
System.Collections.Generic;
class
Program
{
static
Tuple<Tuple<
int
,
int
>,
int
> FindKthSmallestAndCount(List<Tuple<
int
,
int
>> pairs,
int
K, Tuple<
int
,
int
> givenPair)
{
pairs.Sort();
PriorityQueue<Tuple<
int
,
int
>> pq =
new
PriorityQueue<Tuple<
int
,
int
>>((x, y) =>
{
if
(x.Item1 != y.Item1)
return
x.Item1.CompareTo(y.Item1);
return
x.Item2.CompareTo(y.Item2);
});
int
count = 0;
foreach
(Tuple<
int
,
int
> p
in
pairs)
{
if
(p.Item1 < givenPair.Item1 || (p.Item1 == givenPair.Item1 && p.Item2 < givenPair.Item2))
{
count++;
}
pq.Enqueue(p);
if
(pq.Count > K)
{
pq.Dequeue();
}
}
return
new
Tuple<Tuple<
int
,
int
>,
int
>(pq.Peek(), count);
}
static
void
Main()
{
List<Tuple<
int
,
int
>> pairs =
new
List<Tuple<
int
,
int
>>
{
Tuple.Create(23, 20),
Tuple.Create(23, 10),
Tuple.Create(23, 30),
Tuple.Create(12, 35),
Tuple.Create(12, 22)
};
int
K = 3;
Tuple<
int
,
int
> givenPair = Tuple.Create(23, 20);
Tuple<Tuple<
int
,
int
>,
int
> result = FindKthSmallestAndCount(pairs, K, givenPair);
Console.WriteLine(
"{"
+ result.Item1.Item1 +
", "
+ result.Item1.Item2 +
"} "
+ result.Item2);
}
class
PriorityQueue<T>
{
private
List<T> list;
private
Comparison<T> comparison;
public
int
Count {
get
{
return
list.Count; } }
public
PriorityQueue(Comparison<T> comparison)
{
this
.list =
new
List<T>();
this
.comparison = comparison;
}
public
void
Enqueue(T item)
{
list.Add(item);
int
i = list.Count - 1;
while
(i > 0)
{
int
parent = (i - 1) / 2;
if
(comparison(list[parent], item) <= 0)
break
;
list[i] = list[parent];
i = parent;
}
list[i] = item;
}
public
T Dequeue()
{
if
(list.Count == 0)
throw
new
InvalidOperationException(
"Queue is empty"
);
T front = list[0];
int
last = list.Count - 1;
T end = list[last];
list.RemoveAt(last);
if
(last > 0)
{
int
i = 0;
while
(
true
)
{
int
leftChild = i * 2 + 1;
if
(leftChild >= last)
break
;
int
rightChild = leftChild + 1;
int
child = (rightChild < last && comparison(list[rightChild], list[leftChild]) < 0) ? rightChild : leftChild;
if
(comparison(list[child], end) >= 0)
break
;
list[i] = list[child];
i = child;
}
list[i] = end;
}
return
front;
}
public
T Peek()
{
if
(list.Count == 0)
throw
new
InvalidOperationException(
"Queue is empty"
);
return
list[0];
}
}
}