using
System;
using
System.Collections.Generic;
class
Program
{
static
double
MaximizeAverageGoodRatio(List<
int
[]> chocolates,
int
extraChocolates)
{
int
n = chocolates.Count;
double
avg = 0, ans = 0;
PriorityQueue<Tuple<
double
,
int
>> p =
new
PriorityQueue<Tuple<
double
,
int
>>(
new
Comparison<Tuple<
double
,
int
>>((a, b) => b.Item1.CompareTo(a.Item1)));
for
(
int
i = 0; i < n; i++)
{
double
diff = ((
double
)(chocolates[i][0] + 1) / (
double
)(chocolates[i][1] + 1)) - ((
double
)chocolates[i][0] / (
double
)chocolates[i][1]);
p.Enqueue(
new
Tuple<
double
,
int
>(diff, i));
}
while
(extraChocolates > 0)
{
Tuple<
double
,
int
> top = p.Dequeue();
int
i = top.Item2;
chocolates[i][0] += 1;
chocolates[i][1] += 1;
double
diff = ((
double
)(chocolates[i][0] + 1) / (
double
)(chocolates[i][1] + 1)) - ((
double
)chocolates[i][0] / (
double
)chocolates[i][1]);
p.Enqueue(
new
Tuple<
double
,
int
>(diff, i));
extraChocolates--;
}
for
(
int
i = 0; i < n; i++)
{
avg = (
double
)chocolates[i][0] / (
double
)chocolates[i][1];
ans += avg;
}
return
ans / (
double
)n;
}
static
void
Main(
string
[] args)
{
List<
int
[]> chocolates =
new
List<
int
[]>
{
new
int
[] { 1, 2 },
new
int
[] { 3, 5 },
new
int
[] { 4, 4 }
};
int
extraChocolates = 2;
Console.WriteLine(
"Max Average Good Ratio: "
+ MaximizeAverageGoodRatio(chocolates, extraChocolates).ToString(
"F4"
));
}
}
public
class
PriorityQueue<T>
{
private
List<T> data;
private
Comparison<T> comparison;
public
PriorityQueue(Comparison<T> comparison)
{
this
.data =
new
List<T>();
this
.comparison = comparison;
}
public
void
Enqueue(T item)
{
data.Add(item);
int
ci = data.Count - 1;
while
(ci > 0)
{
int
pi = (ci - 1) / 2;
if
(comparison(data[ci], data[pi]) >= 0)
break
;
T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;
ci = pi;
}
}
public
T Dequeue()
{
if
(data.Count == 0)
throw
new
InvalidOperationException(
"Queue is empty"
);
int
li = data.Count - 1;
T frontItem = data[0];
data[0] = data[li];
data.RemoveAt(li);
--li;
int
ci = 0;
while
(
true
)
{
int
pi = ci * 2 + 1;
if
(pi > li)
break
;
int
rc = pi + 1;
if
(rc <= li && comparison(data[rc], data[pi]) < 0)
pi = rc;
if
(comparison(data[ci], data[pi]) <= 0)
break
;
T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;
ci = pi;
}
return
frontItem;
}
public
T Peek()
{
if
(data.Count == 0)
throw
new
InvalidOperationException(
"Queue is empty"
);
return
data[0];
}
public
int
Count
{
get
{
return
data.Count; }
}
}