微信朋友圈上看到一个有意思的算是智力题的东西:

找到所有?代表的数字, 使得以下说法成立:
下面总共有
?个0
?个1
?个2
?个3
?个4
?个5
?个6
?个7
?个8
?个9

注意哦, ?代表的数字, 也要被计数的.

我顺手写了个小程序解出了这个题(可能出题者的本意是让你手算的...)

public class CountNumbers {

    private void copyCount(int[] src, int[] tgt) {
        for (int i = 0; i < src.length; i++) {
            tgt[i] = src[i];
        }
    }

    /**
     * 判定序列是否符合要求
     */
    private boolean compareCount(int[] src, int[] tgt) {
        for (int i = 0; i < src.length; i++) {
            if (tgt[i] != src[i]) {
                return false;
            }
        }
        return true;
    }

    private void printCount(int[] cnt) {
        for (int c : cnt) {
            System.out.print("" + c + " ");
        }
        System.out.println();
    }

    public void countNumbers() {
        // 随机种子
        int[] count = { 2, 2, 2, 3, 3, 5, 5, 6, 6, 7 };
        int[] prevCount = new int[10];

        // 支持多位数
        while (true) {
            this.copyCount(count, prevCount);
            // count for 0~9
            for (int i = 0; i < 10; i++) {
                count[i] = 1;
            }
            for (int cnt : prevCount) {
                String cntStr = String.valueOf(cnt);
                for (char c : cntStr.toCharArray()) {
                    count[c - '0']++;
                }
            }
            this.printCount(count);
            if (compareCount(count, prevCount)) {
                System.out.println("found !");
                break;
            }
        }
    }

    public static void main(String[] args) {
        CountNumbers cn = new CountNumbers();
        cn.countNumbers();
    }
}

想法很简单, 不期望一次找对, 每次迭代都数一下目前包含的数字个数, 直到正确为止. 当然, 这种解法的前提是, 这么做是会收敛的.这个解法支持?代表的数是多位数.

其中有一串数字, 是count的初始值, 这个可以随意给出, 并且会发现, 如果给出的值不同, 可能导致解出的结果不同. 但只要停止, 给出的就是正确的解. 代码中给出的这串数字, 输出的解都是一位数.

执行结果为:

1 1 4 3 1 3 3 2 1 1 
1 6 2 4 2 1 1 1 1 1 
1 7 3 1 2 1 2 1 1 1 
1 7 3 2 1 1 1 2 1 1 
1 7 3 2 1 1 1 2 1 1 
found !

最后一行数字就是题目中的解, 可以验证下:)


EthanSun
45 声望3 粉丝