找回密码
 欢迎注册
楼主: 毒酒滴冻鸭

[讨论] 织女的六把黄金尺子问题

[复制链接]
发表于 2014-12-16 14:21:07 | 显示全部楼层


对称性!
如1号尺
1 5 30 36 50 53 转为差分形式  1 4 25 6 14 3
3 17 23 48 52 53 转为差分形式  3 14 6 25 4 1

6把尺子的一个解,正反表示,有$2^5=32$ 种组合。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-12-16 14:24:05 | 显示全部楼层
我还在算,不过我加入了消对称代码

出来了
  1. 1 4 25 6 14 3
  2. 8 10 16 12 9
  3. 2 22 19 13
  4. 7 33 11
  5. 15 27
  6. 39
复制代码

点评

如果可以的话不妨穷搜一下其它数量的尺子:五尺子量1..35、四尺子量1..20、三尺子量1..10、二尺子量1..4。。。七尺子量1..84这个应该无解,但很花时间验证。。。  发表于 2014-12-16 14:44
很好,跟1楼图片的数据相同。。。希望能完整搜寻,然后记录总用时。。。  发表于 2014-12-16 14:41
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2014-12-16 14:48:13 | 显示全部楼层
这里大神果然很多。。。这道题算是一个不错的编程习作吧。。。手上还有几个很需要编程高手功力的数学趣题,有空提出研究!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-12-16 15:09:54 来自手机 | 显示全部楼层
消除对称时间可以减少到两分多。如果每个尺子的表示中首段小于尾段,时间将近3分钟,如果改成将最靠近中间两刻度消除对称情况,时间可缩减到略大于2分
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-12-16 15:44:22 | 显示全部楼层
如果略作修改,要求测量连续整数的区间跨度尽可能大,答案是否还是一样?会不会更复杂?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2014-12-16 19:41:54 | 显示全部楼层
mathe 发表于 2014-12-16 15:09
消除对称时间可以减少到两分多。如果每个尺子的表示中首段小于尾段,时间将近3分钟,如果改 ...


这是用中科院级的超级电脑运算还是一般的个人电脑?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2014-12-16 19:43:39 | 显示全部楼层
rulers6.png

这是一楼的图配上各段长度标识,跟15#的数据一致。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-12-16 19:44:29 来自手机 | 显示全部楼层
普通个人电脑
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2014-12-16 19:51:35 | 显示全部楼层
  1. #include <iostream>
  2. using namespace std;

  3. const int N = 6;   //number of rulers
  4. const int MAX = N*(N+1)*(N+2)/6;   //number of lengths

  5. int i, j;          //indexes for traversing array
  6. int temp[N+1];     //temp lengths for current ruler
  7. int b[MAX+1];      //for checking repeat lengths
  8. int a[N+1][N+1];   //answer array

  9. int back()   //back one section
  10. {
  11.   a[i][j] = 0;
  12.   j--;
  13.   if (j == 0) {i++; j = i;}
  14.   return 0;
  15. }

  16. int next()   //forward to next section
  17. {
  18.   j++;
  19.   if (j > i) {i--; j = 1;}
  20.   return 0;   
  21. }

  22. int showAnswer()   //show an anwser
  23. {
  24.   int i, j;

  25.   for (i = N; i > 0; i--)
  26.   {
  27.      for (j = i; j > 1; j--) cout << a[i][j] << ",";
  28.      cout << a[i][1] << "|";
  29.   }
  30.   cout << endl;
  31.   return 0;
  32. }

  33. int check()   //check for duplicated or invalid lengths
  34. {
  35.   int m;

  36.   if (a[i][i] > a[i][1]) return 1;   //ruler in wrong direction
  37.   temp[0] = a[i][j];
  38.   for (m = 1; m < j; m++)
  39.   {
  40.     temp[m] = temp[m-1] + a[i][j-m];
  41.     if (temp[m] > MAX) return 1;   //length exceeds MAX
  42.     if (b[temp[m]]) return 2;   //length exists already
  43.   }
  44.   for (m = 0; m < j; m++) b[temp[m]] = 1;
  45.   return 0;
  46. }

  47. int cancel()   //cancel and rollback current section
  48. {
  49.   int m;

  50.   temp[0] = a[i][j];
  51.   b[temp[0]] = 0;
  52.   for (m = 1; m < j; m++)
  53.   {
  54.     temp[m] = temp[m-1] + a[i][j-m];
  55.     b[temp[m]] = 0;
  56.   }
  57.   return 0;
  58. }

  59. int main()
  60. {
  61.   int flag, count = 0;

  62.   // initialisation
  63.   for (i = 0; i <= N; i++) for (j = 0; j <= N; j++) a[i][j] = 0;
  64.   for (i = 0; i <= MAX; i++) b[i] = 0;

  65.   i = N, j = 1;   // start at last ruler, first section
  66.   while (1)
  67.   {
  68.     if (a[i][j] && b[a[i][j]]) cancel();   // rollback previous actions
  69.     a[i][j]++;
  70.     if (i == N && j == 1) cout << "[" << a[i][j] << "]" << endl;   //track progress
  71.     while (b[a[i][j]] && a[i][j] + a[i][j-1] <= MAX) a[i][j]++;
  72.     if (a[i][j] + a[i][j-1] > MAX)
  73.     {
  74.       back();
  75.       if (i > N) break;
  76.     }
  77.     else
  78.     {
  79.       flag = check();
  80.       if (flag == 0)
  81.       {
  82.         if (i == 1)
  83.         {
  84.           count++;
  85.           showAnswer();
  86.         }
  87.         else next();
  88.       }
  89.       else if (flag == 1)
  90.       {
  91.         back();
  92.         if (i > N) break;
  93.       }
  94.     }
  95.   }
  96.   cout << "\nThe number of answers is: " << count << endl;
  97.   return 0;
  98. } //rulers.cpp
复制代码

这个C++程序是根据几年前百度贴吧一位吧友的算法改编而成,可能不及mathe站主的C程序有效率,在我的core-i7手提电脑上也要运行接近十分钟才完成穷搜。。。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-12-16 21:38:40 来自手机 | 显示全部楼层
我的台式机性能应该比笔记本好。core i7 3.7GHz
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-12-22 11:29 , Processed in 0.026145 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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