C♯の勉強

C♯4.0 で TopCoder の過去問を解きます。

TopCoder SRM581: TreeUnionDiv2

public class TreeUnionDiv2 {
    int[,] warshallFloyd(string[] tree) {
        int n = tree.Length;
        var d = new int[n, n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                d[i, j] = tree[i][j] == 'X' ? 1 : 1<<28;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    d[j, k] = Math.Min(d[j, k], d[j, i] + d[i, k]);
                }
            }
        }
        return d;
    }

    static public void Swap<T>(ref T a, ref T b) {
        T t = a;
        a = b;
        b = t;
    }

    static public bool NextPermutation<T>(T[] array) where T : IComparable<T> {
        int n = array.Length;
        for (int i = n - 2; i >= 0; i--) {
            if (array[i].CompareTo(array[i + 1]) < 0) {
                var index = Array.FindLastIndex(array, v => array[i].CompareTo(v) < 0);
                Swap(ref array[i], ref array[index]);
                Array.Reverse(array, i + 1, n - (i + 1));
                return true;
            }
        }
        Array.Reverse(array);
        return false;
    }

    public int maximumCycles(string[] tree1, string[] tree2, int K) {
        int n = tree1.Length;
        var perm = Enumerable.Range(0, n).ToArray();
        var d1 = warshallFloyd(tree1);
        var d2 = warshallFloyd(tree2);
        int ans = 0;
        do {
            int num = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < i; j++) {
                    int ti = perm[i];
                    int tj = perm[j];
                    int loopLength = d1[i, j] + d2[ti, tj] + 2;
                    if (loopLength == K) num++;
                }
            }
            ans = Math.Max(ans, num);
        } while (NextPermutation(perm));
        return ans;
    }
}