知恵袋の数字を並べて作る整数の個数の問題を解いてみた。

 知恵袋の数字を並べて作る整数の個数の問題を解いてみました。

 6個の数字0、1、2、3、4、5がある。
 この時、異なる3個の数字を用いてできる3桁の数のうち3の倍数はいくつあるか。

 まず、条件を満たす組合せを求めてから、順列を求めるパターンです。

{0,1,2},
{0,1,5},{0,2,4},{1,2,3},
{0,4,5},{1,3,5},{2,3,4},
{3,4,5}

∴4*3!+4*(2*2!)=40

● PermWithCond1.java

/* 
 * PermWithCond1.java
 */

class PermWithCond1 {
    // 順列生成
    static boolean nextPerm(int[] p, int n, int r) {
        int i, j;
        int t;
        
        if(r <= 0 || n < r) return(false);
        for(i = r + 1; i <= n-1; i++)
            for(j = i; j >= r + 1 && p[j-1] < p[j]; j--){
                t = p[j]; p[j] = p[j-1]; p[j-1] = t;    // swap(p,j,j-1);
            }
        for(i = n - 1; i > 0 && p[i-1] >= p[i]; i--);
        if(i==0) return(false);
        for(j = n - 1; j > i && p[i-1] >= p[j]; j--);
        t = p[j]; p[j] = p[i-1]; p[i-1] = t;            // swap(p,j,i-1);
        for(j = n - 1; i < j; i++, j--){
            t = p[i]; p[i] = p[j]; p[j] = t;            // swap(p,i,j);
        }
        return(true);
    }
    
    public static void main(String[] args) {
        final int N = 6, R = 3;
        int[] p = {0,1,2,3,4,5};
        int   count=0;
        
        long tm=System.nanoTime();      // Timer Start
        do{
            int n=100*p[0]+10*p[1]+p[2];
            if(n< 100) continue;
            if(n%3!=0) continue;
            // チェックを潜り抜けたものだけをカウント
            count++;
            //System.out.println(n);
        } while(nextPerm(p,N,R));
        System.out.println("count="+count);
        tm=System.nanoTime()-tm;        // Timer Stop
        System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9);
    }
}

●実行結果

count=40
Runtime : 0.001 [sec]