import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
static void swap(int indices[], int a, int b)
{
int temp = indices[a];
indices[a] = indices[b];
indices[b] = temp;
}
static boolean beat(int i, int j)
{
if (i < j)
return games[i][j] == 1;
else
return games[j][i] == 0;
}
static int loser(int i, int j)
{
if (beat(i, j))
return j;
else
return i;
}
static void removeIndex(int i)
{
swap(indices, i, --indicesCount);
}
static int n = 100;
static int[][] games = new int[n][n];
static int[] indices = new int[n];
static int indicesCount = n;
{
for (int j = 0; j < n; j++)
for (int i = 0; i < j; i++)
// doing this heavily biases higher values for wins
// since we're only filling in the top-right half of the matrix
if (random.nextInt(n/5) == 0) games[i][j] = 1;
// solve this problem using brute force to validate the correctness of the algorithm
int[] losses = new int[n];
for (int j = 0; j < n; j++)
for (int i = 0; i < j; i++)
losses[loser(i, j)]++;
Set<Integer> output = new TreeSet<Integer>();
for (int i = 0; i < n; i++)
if (losses[i] <= 10)
output.add(i);
System.
out.
println("Brute force winners: " + output
);
for (int i = 0; i < n; i++)
indices[i] = i;
losses = new int[n];
for (int a = 0; a < indicesCount; )
{
for (int b = a+1; losses[indices[a]] <= 10 && b < indicesCount; )
{
losses[loser(indices[a], indices[b])]++;
if (losses[indices[b]] > 10)
removeIndex(b);
else
b++;
}
if (losses[indices[a]] > 10)
removeIndex(a);
else
a++;
}
output.clear();
for (int i = 0; i < indicesCount; i++)
{
int lossCount = 0;
for (int j = 0; j < n; j++)
if (indices[i] == j)
continue;
else if (beat(j, indices[i]))
lossCount++;
if (lossCount <= 10)
output.add(indices[i]);
}
System.
out.
println("O(n) algorithm winners: " + output
); }
}