找回密码
 欢迎注册
楼主: fallening

[讨论] 发现一很有趣的题目,讨论一下吧

[复制链接]
发表于 2008-9-9 15:24:44 | 显示全部楼层
第一种是最笨的方法:把每一位从0到9都尝试过,然后再次统计这个数组得到另外一个结果,如果两个数组相等就表明成功,否则就失败。但是这个方法算法太耗时间,不推荐,如果面试的时候能够讲出这种方法,估计面试官还是会给一点分的!
第二种:因为总共出现的总次数为10,所以我们可以很有效的利用这个属性,进行一次排列,为了分析简单,我们从最大开始:
9+1+n*0(n=8),对这个数据进行整理得8100000001,再次对这个数组进行统计分析得7200000010,与刚得到的数组不一样,错误,转到下一个排列
8+2+n*0(n=8),对这个数据进行整理得8010000010,再次对这个数组进行统计分析得7200000010,与刚得到的数组不一样,错误,转到下一个排列
8+1+1+n*0(n=7),对这个数据进行整理得7200000010,再次对这个数组进行统计分析得7110000100,与刚得到的数组不一样,错误,转到下一个排列
....
总共的排列数:
9  1  0  0  0  0  0  0  0  0
8  2  0  0  0  0  0  0  0  0
8  1  1  0  0  0  0  0  0  0
7  3  0  0  0  0  0  0  0  0
7  2  1  0  0  0  0  0  0  0
7  1  1  1  0  0  0  0  0  0
6  4  0  0  0  0  0  0  0  0
6  3  1  0  0  0  0  0  0  0
6  2  2  0  0  0  0  0  0  0
6  2  1  1  0  0  0  0  0  0
6  1  1  1  1  0  0  0  0  0
5  5  0  0  0  0  0  0  0  0
5  4  1  0  0  0  0  0  0  0
5  3  2  0  0  0  0  0  0  0
5  3  1  1  0  0  0  0  0  0
5  2  2  1  0  0  0  0  0  0
5  2  1  1  1  0  0  0  0  0
5  1  1  1  1  1  0  0  0  0
4  4  2  0  0  0  0  0  0  0
4  4  1  1  0  0  0  0  0  0
4  3  3  0  0  0  0  0  0  0
4  3  2  1  0  0  0  0  0  0
4  3  1  1  1  0  0  0  0  0
4  2  2  2  0  0  0  0  0  0
4  2  2  1  1  0  0  0  0  0
4  2  1  1  1  1  0  0  0  0
4  1  1  1  1  1  1  0  0  0
3  3  3  1  0  0  0  0  0  0
3  3  2  2  0  0  0  0  0  0
3  3  2  1  1  0  0  0  0  0
3  3  1  1  1  1  0  0  0  0
3  2  2  2  1  0  0  0  0  0
3  2  2  1  1  1  0  0  0  0
3  2  1  1  1  1  1  0  0  0
3  1  1  1  1  1  1  1  0  0
2  2  2  2  2  0  0  0  0  0
2  2  2  2  1  1  0  0  0  0
2  2  2  1  1  1  1  0  0  0
2  2  1  1  1  1  1  1  0  0
2  1  1  1  1  1  1  1  1  0
1  1  1  1  1  1  1  1  1  1
也就是说,对这个数据无论进行过多少次统计,它的值都还是等于原值的排列,才是正确的排列
算法如下:(没有注释及缩进的算法,见笑了*^_^*)
(且这个程序必须假定A数组为初始值0增量1的等差数列)
  1. C/C++ code
  2. #include <iostream>

  3. using namespace std;

  4. const int N = 10;
  5. int source[N];
  6. int dest[N] = {0};
  7. int dest2[N] = {0};

  8. void init()
  9. {
  10.     for(int i=0; i<N; i++)
  11.     {
  12.         source[i] = i;
  13.     }
  14. }

  15. void display(int target[])
  16. {
  17.     for(int i=0; i<N; i++)
  18.     {
  19.         printf("%4d", target[i]);
  20.     }
  21.     cout << endl;
  22. }

  23. /*
  24.     从src的数据统计出现的次数并存入dest中
  25.     Create by Denny, Email: [email]silitex@yeah.net[/email]
  26. */
  27. void count(int *dest, int *src)
  28. {
  29.     int i;

  30.     for (i = 0; i < N; i++)    // dest清0
  31.         dest[i] = 0;
  32.     for (i = 0; i < N; i++)    // 整理当前的数值到正确的位置上
  33.         dest[src[i]]++;
  34. }

  35. void main()
  36. {
  37.     init();
  38.     display(source);    // 原始数组

  39.     int tmp[N] = {N-1};    // 默认给第一个赋值为N-1
  40.     int posi = 0;
  41.     while (posi >= 0)
  42.     {
  43.         int i = 0;
  44.         int leave = N;
  45.         int min = tmp[0];
  46.         for (; i <= posi; i++)
  47.         {
  48.             leave -= tmp[i];
  49.             if (tmp[i] < min)
  50.                 min = tmp[i];
  51.         }
  52.         for (; i < N; i++)
  53.             tmp[i] = 0;
  54.         while (leave > 0)
  55.         {
  56.             if (min > leave)
  57.                 min = leave;
  58.             tmp[++posi] = min;
  59.             leave -= min;
  60.         }

  61.         count(dest, tmp);    // 初步统计,得到一个正确的数值
  62.         count(dest2, dest);    // 再次进行统计
  63.         for (i = 0; i < N; i++)    // 核对结果
  64.             if (dest2[i] != dest[i])
  65.                 break;
  66.         if (i >= N)            // 正确结果,显示答案
  67.             display(dest);

  68.         while (--tmp[posi] == 0)
  69.             posi--;
  70.     }
  71. }
复制代码
得到10位数的答案有且仅有一个:
6  2  1  0  0  0  1  0  0  0
9位数答案(只有一个):
5  2  1  0  0  1  0  0  0
8位数答案(只有一个):
4  2  1  0  1  0  0  0
7位数答案(只有一个):
3  2  1  1  0  0  0
6位数无解
5位数答案(只有一个):
2  1  2  0  0
4位数答案:
2  0  2  0
1  2  1  0
3位数无解
2位数无解
1位数无解
11位数答案(只有一个):
7  2  1  0  0  0  0  1  0  0  0
12位数答案(只有一个):
8  2  1  0  0  0  0  0  1  0  0  0
13位数答案(只有一个):
9  2  1  0  0  0  0  0  0  1  0  0  0
14位数答案(只有一个):
10  2  1  0  0  0  0  0  0  0  1  0  0  0
15位数答案(只有一个):
11  2  1  0  0  0  0  0  0  0  0  1  0  0  0
16位数答案(只有一个):
12  2  1  0  0  0  0  0  0  0  0  0  1  0  0  0
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-21 12:14:34 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-21 12:15:49 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-21 12:16:41 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-18 20:05 , Processed in 0.042003 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表