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

[擂台] 最小无法表达的正整数

[复制链接]
 楼主| 发表于 2008-8-4 11:28:48 | 显示全部楼层
我只用过gdb,不过我是用ddd(提供的图形界面还可以),它封装的gdb.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 16:01:14 | 显示全部楼层
要疯了 怎么也无法枚举每种状态 已解决加乘的左右交换问题 但对减除的左面是树,右面是叶子的 表达式树,怎么也无法枚举出来 枚举打印的都缺少叶子,哎
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 16:02:40 | 显示全部楼层
重新写的求值函数
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/time.h>
  4. #define max 16
  5. #define nmax 64 * 1024 * 1024
  6. int calc[2 * max - 1];
  7. int operator[4] = { -1, -3, -2, -4 }; // + * - /
  8. int mask[max + 1]; //代表数字是否被使用
  9. int nmask[nmax]; //表示的数字
  10. int n;
  11. int leaf; //剩余数字
  12. int position;
  13. int counter;
  14. void
  15. init (void)
  16. {
  17. int i;
  18. for (i = 1; i <= max; i++)
  19. mask[i] = 0;
  20. position = 0;
  21. counter = 0;
  22. leaf = n;
  23. memset(nmask, 0, nmax * sizeof(int));
  24. }
  25. void search(void)
  26. {
  27. int i;
  28. for (i = 1; i < nmax; i ++)
  29. if (nmask[i] == 0)
  30. {
  31. printf("\nmin: %d\n", i);
  32. break;
  33. }
  34. }
  35. //返回0代表表达式合法,-1代表除法不能除尽,-2代表除以0,-3代表结果为负
  36. int print(void)
  37. {
  38. int i;
  39. int opTop = 0, numTop = 0;
  40. long long temp;
  41. long long numBuffer[max];
  42. int itemp;
  43. for (i = 2 * n - 2; i >= 0; i --)
  44. {
  45. if (calc[i] < 0)
  46. {
  47. switch (calc[i])
  48. {
  49. case -1:
  50. temp = numBuffer[numTop - 1] + numBuffer[numTop - 2];
  51. break;
  52. case -2:
  53. temp = numBuffer[numTop - 1] - numBuffer[numTop - 2];
  54. break;
  55. case -3:
  56. temp = numBuffer[numTop - 1] * numBuffer[numTop - 2];
  57. break;
  58. case -4:
  59. if (numBuffer[numTop - 2] == 0)
  60. return (-2);
  61. if (numBuffer[numTop - 1] % numBuffer[numTop - 2] > 0)
  62. return (-1);
  63. temp = numBuffer[numTop - 1] / numBuffer[numTop - 2];
  64. break;
  65. }
  66. numTop -= 1;
  67. numBuffer[numTop - 1] = temp;
  68. }
  69. else
  70. numBuffer[numTop ++] = calc[i];
  71. }
  72. temp = numBuffer[0];
  73. if (temp < 0) return (-3);
  74. if (temp < nmax)
  75. {
  76. itemp = temp;
  77. if (nmask[itemp] == 0)
  78. {
  79. counter++;
  80. printf("%d: %d ", counter, itemp);
  81. for (i = 0; i <= 2 * n - 2; i++)
  82. {
  83. if (calc[i] < 0)
  84. {
  85. switch (calc[i])
  86. {
  87. case -1:
  88. printf ("+ ");
  89. break;
  90. case -2:
  91. printf ("- ");
  92. break;
  93. case -3:
  94. printf ("* ");
  95. break;
  96. case -4:
  97. printf ("/ ");
  98. break;
  99. }
  100. }
  101. else
  102. printf ("%d ", calc[i]);
  103. }
  104. printf ("\n");
  105. nmask[itemp] = 1;
  106. }
  107. }
  108. return (0);
  109. }
  110. int
  111. printOnly (void)
  112. {
  113. int i;
  114. for (i = 0; i <= 2 * n - 2; i++)
  115. {
  116. if (calc[i] < 0)
  117. {
  118. switch (calc[i])
  119. {
  120. case -1:
  121. printf ("+ ");
  122. break;
  123. case -2:
  124. printf ("- ");
  125. break;
  126. case -3:
  127. printf ("* ");
  128. break;
  129. case -4:
  130. printf ("/ ");
  131. break;
  132. }
  133. }
  134. else
  135. printf ("%d ", calc[i]);
  136. }
  137. printf ("\n");
  138. counter++;
  139. }
  140. void
  141. printBlank (void)
  142. {
  143. counter++;
  144. }
  145. int
  146. top (int MaxNode)
  147. {
  148. int i;
  149. if (MaxNode >= 1)
  150. for (i = 0; i < 4; i++)
  151. {
  152. calc[position++] = operator[i];
  153. if (i < 2)
  154. subNode (MaxNode - 1, 1);
  155. else
  156. subNode (MaxNode - 1, 0);
  157. position--;
  158. }
  159. }
  160. void
  161. addmul (void)
  162. {
  163. int i, j;
  164. for (i = 1; i <= n - 1; i++)
  165. if (mask[i] == 0)
  166. {
  167. mask[i] = 1;
  168. leaf--;
  169. calc[position++] = i;
  170. for (j = i + 1; j <= n; j++)
  171. if (mask[j] == 0)
  172. {
  173. calc[position++] = j;
  174. mask[j] = 1;
  175. leaf--;
  176. if (leaf == 0)
  177. {
  178. // check();
  179. print ();
  180. }
  181. mask[j] = 0;
  182. leaf++;
  183. position--;
  184. }
  185. leaf++;
  186. position--;
  187. mask[i] = 0;
  188. }
  189. }
  190. void
  191. subdiv (void)
  192. {
  193. int i, j;
  194. for (i = 1; i <= n; i++)
  195. if (mask[i] == 0)
  196. {
  197. mask[i] = 1;
  198. leaf--;
  199. calc[position++] = i;
  200. for (j = 1; j <= n; j++)
  201. if (mask[j] == 0)
  202. {
  203. calc[position++] = j;
  204. mask[j] = 1;
  205. leaf--;
  206. if (leaf == 0)
  207. {
  208. // check();
  209. print ();
  210. }
  211. mask[j] = 0;
  212. leaf++;
  213. position--;
  214. }
  215. leaf++;
  216. position--;
  217. mask[i] = 0;
  218. }
  219. }
  220. void
  221. leftFill (int MaxNode)
  222. {
  223. int i;
  224. for (i = 1; i <= n; i++)
  225. if (mask[i] == 0)
  226. {
  227. calc[position++] = i;
  228. leaf--;
  229. mask[i] = 1;
  230. top (MaxNode);
  231. position--;
  232. leaf++;
  233. mask[i] = 0;
  234. }
  235. }
  236. void
  237. rightFill (int MaxNode)
  238. {
  239. int i;
  240. for (i = 1; i <= n; i++)
  241. if (mask[i] == 0)
  242. {
  243. mask[i] = 1;
  244. calc[position + 2 * MaxNode + 1] = i;
  245. leaf--;
  246. top (MaxNode);
  247. leaf++;
  248. mask[i] = 0;
  249. }
  250. }
  251. int
  252. subNode (int MaxNode, int exchange)
  253. {
  254. int i, j;
  255. if (MaxNode == 0)
  256. {
  257. if (exchange == 1)
  258. addmul ();
  259. else
  260. subdiv ();
  261. }
  262. if (MaxNode >= 1)
  263. {
  264. //1\fill left
  265. leftFill (MaxNode);
  266. //2\fill right
  267. if (exchange == 0)
  268. rightFill (MaxNode);
  269. }
  270. //3\top(left) top(right)
  271. if (MaxNode >= 2)
  272. for (i = 1; i < MaxNode; i++)
  273. {
  274. top (i);
  275. top (MaxNode - i);
  276. }
  277. }
  278. int
  279. main (void)
  280. {
  281. struct timeval start, end;
  282. double timeuse;
  283. printf ("Input n value:");
  284. scanf ("%d", &n);
  285. printf ("\n\n");
  286. gettimeofday (&start, NULL);
  287. init ();
  288. top (n - 1);
  289. printf ("\nTotal: %d\n", counter);
  290. search();
  291. gettimeofday (&end, NULL);
  292. timeuse =
  293. 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
  294. timeuse /= 1000000;
  295. printf ("\n\nUsed Time:%8.6f\n\n", timeuse);
  296. return 0;
  297. }
复制代码
n <=5和mathe的答案一致 从6开始就不对了 在查找原因 [ 本帖最后由 无心人 于 2008-8-4 21:48 编辑 ]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 18:42:42 | 显示全部楼层
n = 7的算下 一会儿过来汇报 ============= Total: 2710 min: 1102 Used Time:105.265166 =============== 晕,似乎从6开始就和mathe的结果不同了啊 哎 [ 本帖最后由 无心人 于 2008-8-4 18:46 编辑 ]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-8-4 18:52:31 | 显示全部楼层
1102=2*(5+7*6*(1+4*3))
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 18:55:50 | 显示全部楼层
有bug,从3开始就不对了 还没找到问题 我把7的都输出到文件,看是漏算还是计算函数有问题 ======================= 已修正n到5 但从6开始还不对,有两个无法算出 279 281 [ 本帖最后由 无心人 于 2008-8-4 21:56 编辑 ]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-8-4 18:56:51 | 显示全部楼层
279=(5+4)*(1+6*(3+2))
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 19:24:39 | 显示全部楼层
晕死 7的输出3G多 文本编辑器打不开阿 推荐个能处理这么大文件的文本编辑器 ================ 看n=3的结果 里面有7的结果 + 1 * 2 3 但不输出7 似乎是求值的问题 [ 本帖最后由 无心人 于 2008-8-4 19:28 编辑 ]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 19:32:29 | 显示全部楼层
Input n value: 3 1: 6 + 1 + 2 3 2: 7 + 1 * 2 3 3: 0 + 1 - 2 3 4: 2 + 1 - 3 2 5: 5 + 2 * 1 3 6: 4 + 2 - 3 1 7: 1 * 1 - 3 2 8: 8 * 2 + 1 3 9: 9 * 3 + 1 2 10: 3 * 3 - 2 1 Total: 10 min: 10 Used Time:1.113455 [ 本帖最后由 无心人 于 2008-8-4 21:47 编辑 ]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-8-4 21:37:55 | 显示全部楼层
mathe 6的还一个281没找到解 你的解是?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-12-22 11:17 , Processed in 0.025321 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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