SRM146_DIV2

這次的題獨立搞出來了前兩道,可喜可賀

250

相同的數字加一起,找最大的和,因爲是骰子,所以就是長度爲6的數組

public class YahtzeeScore{
    public int maxPoints(int[] toss){
        int[] result = new int[6];
        for (int i : toss){
            result[i - 1] += i;
        }
        int max = 0;
        for (int i : result){
            max = Math.max(i, max);
        }
        return max;
    }
}

500

長方體中的小長方體(不包括正方體)個數,找出所有的長寬組合就行~

public class RectangularGrid{
    public long countRectangles(int width, int height){
        long result = 0;
        for (int i = 1; i <= width; i++){
            for (int j = 1; j <= height; j++){
                if ( i == j) continue;
                result += (width + 1 - i) * (height + 1 - j);
            }
        }
        return result;
    }
}

1000

過河問題,這個題不會,看了別人的兩種答案,一種是思考簡單但是編程困難的窮舉,一種是思考麻煩編程簡單的方法

第一種是簡單的遞歸調用吧

import java.util.Arrays;

public class BridgeCrossing{
    private boolean[] leftSide;
    private boolean[] rightSide;
    private int minTime = Integer.MIN_VALUE;
    private int time = 0;

    public int minTime(int[] times){
        int length = times.length;
        if (length == 1){
            return times[0];
        }

        leftSide = newBooleanArray(length, true);
        rightSide = newBooleanArray(length, false);
        goToTheRight(times);

        return minTime;
    }

    private boolean[] newBooleanArray(int length, boolean b){
        boolean[] array = new boolean[length];
        Arrays.fill(array, b);
        return array;
    }

    private void goToTheRight(int[] times){
        for( int i = 0; i < times.length - 1; i++){
            if(!leftSide[i]) continue;

            for (int j = i + 1; j < times.length; j++){
                if(!leftSide[j]) continue;

                // next state
                leftSide[i] = leftSide[j] = false;
                rightSide[i] = rightSide[j] = true;
                int t = Math.max(times[i], times[j]);
                time += t;

                goToTheLeft(times);

                // reset state
                time -= t;
                leftSide[i] = leftSide[j] = true;
                rightSide[i] = rightSide[j] = false;
            }
        }
    }

    private void goToTheLeft(int[] times){
        if(allTrue(rightSide)){
            minTime = Math.min(minTime, time);
        }else{
            for( int i = 0; i < times.length; i++){
                if(!rightSide[i]) continue;

                // next state
                rightSide[i] = false;
                leftSide[i] = true;
                time += times[i];

                goToTheRight(times);

                // rest state
                time -= times[i];
                rightSide[i] = true;
                leftSide[i] = false;
            }
        }
    }
    private boolean allTrue(boolean[] rightSide){
        for(boolean b : rightSide){
            if(!b) return false;
        }
        return true;
    }
}

第二種,首先如果人數小於等於3就分情況討論下,大於3則把行動最快的兩個作爲運送手電的橋樑,每完成一個輪迴就會把兩個目前最慢的人搬到對面。不停重複直到剩下的人數小於等於3。

import java.util.Arrays;

public class BridgeCrossing{
    public int minTime(int[] times){
        int total = 0, remaining = times.length;
        Arrays.sort(times);

        while (remaining > 3){
            total += Math.min(times[0] * 2 + times[remaining - 2] + times[remaining - 1], times[0] + times[1] * 2 + times[remaining - 1]);
            remaining -= 2;
        }

        switch (remaining){
            case 1:
                return times[0];
            case 2:
                return total += times[1];
            case 3:
                return total += times[0] + times[1] + times[2];
            default:
                break;
        }
        return total;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章