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

[提问] N×N的方格,里面有多少个长方形?

[复制链接]
发表于 2013-3-19 14:23:15 | 显示全部楼层
立体情况下 (1,1) (2,36) (3,372) (4,2032) (5,8107) (6,24986) (7,66688) (8,155896)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2013-3-19 15:45:51 | 显示全部楼层
31# 无心人 有通项公式就更好了 那是不可能的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-3-19 15:51:34 | 显示全部楼层
31# 无心人 新数列么,貌似在OEIS上搜不到
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-3-19 16:06:56 | 显示全部楼层
奉上C++代码
  1. #include <iostream>
  2. using namespace std;
  3. #define MAX 99
  4. struct point3
  5. {
  6. int x, y, z, dp;
  7. };
  8. point3 point[(MAX+1)*(MAX+1)*(MAX+1)];
  9. int dp(int n,int x, int y,int z)
  10. {
  11. return (x + (n+1)*y + (n+1)*(n+1)*z);
  12. }
  13. void init(int n)
  14. {
  15. int x, y, z;
  16. for (z=0;z<=n;z++)
  17. for (y=0;y<=n; y++)
  18. for (x=0;x<=n; x++)
  19. {
  20. int t= x+(n+1)*y+(n+1)*(n+1)*z;
  21. point[t].x = x;
  22. point[t].y = y;
  23. point[t].z = z;
  24. point[t].dp = dp(n, x, y, z);
  25. }
  26. }
  27. int orth(point3 p0, point3 p1,point3 p2)
  28. {
  29. return ((p1.x-p0.x)*(p2.x-p0.x) + (p1.y-p0.y)*(p2.y-p0.y) + (p1.z-p0.z)*(p2.z-p0.z))==0;
  30. }
  31. void addp2(point3& r, point3 p0, point3 p1, point3 p2)
  32. {
  33. r.x=p1.x+p2.x-p0.x;
  34. r.y=p1.y+p2.y-p0.y;
  35. r.z=p1.z+p2.z-p0.z;
  36. }
  37. void addp3(point3& r, point3 p0, point3 p1, point3 p2, point3 p3)
  38. {
  39. r.x=p1.x+p2.x+p3.x-2*p0.x;
  40. r.y=p1.y+p2.y+p3.y-2*p0.y;
  41. r.z=p1.z+p2.z+p3.z-2*p0.z;
  42. }
  43. int inside(int n, point3 p)
  44. {
  45. return (p.x<=n)&&(p.x>=0)&&(p.y<=n)&&(p.y>=0)&&(p.z<=n)&&(p.z>=0);
  46. }
  47. long long calc(int n)
  48. {
  49. if (n < 1) return 0;
  50. if (n == 1) return 1;
  51. point3 t;
  52. long long c=0;
  53. init(n);
  54. int max=(n+1)*(n+1)*(n+1)-1;
  55. for (int i=0; i<=max-3; i ++)
  56. for (int j=i+1; j<=max-2; j ++)
  57. for (int k=j+1; k<=max-1; k ++)
  58. if (orth(point[i], point[j], point[k]))
  59. for (int m=k+1; m<=max; m ++)
  60. {
  61. if (orth(point[i], point[j], point[m]))
  62. if (orth(point[i], point[m], point[k]))
  63. {
  64. addp2(t, point[i], point[j], point[k]);
  65. if (inside(n, t))
  66. {
  67. addp2(t, point[i], point[m], point[k]);
  68. if (inside(n, t))
  69. {
  70. addp2(t, point[i], point[j], point[m]);
  71. if (inside(n, t))
  72. {
  73. addp3(t, point[i], point[j], point[k], point[m]);
  74. if (inside(n, t)) c++;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. return c;
  81. }
  82. int main( void )
  83. {
  84. int n;
  85. cout << "input: ";
  86. cin >> n;
  87. cout << endl;
  88. if (n > MAX) cout << "input is to BIG" << endl;
  89. cout << "total: " << calc(n);
  90. return 0;
  91. }
复制代码
这个程序还可以深度优化的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-3-19 16:08:26 | 显示全部楼层
(9,332657) (10,653708) (11,1216076) (12, 2135220) (13,3604679) (14,5845214) (15,9160864) (16,13947880) (17,20778029) (18,30205036) (19,43114824)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-3-19 16:14:10 | 显示全部楼层
33# wayne 是的,我也搜不到 不过急需有人进行复检。。。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-3-19 19:29:27 | 显示全部楼层
优化了一下 数字较大时候,缩短的时间很可观
  1. #include <iostream>
  2. using namespace std;
  3. #define MAX 99
  4. struct point3
  5. {
  6. int x, y, z, dp;
  7. };
  8. point3 point[(MAX+1)*(MAX+1)*(MAX+1)];
  9. int dp(int n,int x, int y,int z)
  10. {
  11. return (x + (n+1)*y + (n+1)*(n+1)*z);
  12. }
  13. void init(int n)
  14. {
  15. int x, y, z;
  16. for (z=0;z<=n;z++)
  17. for (y=0;y<=n; y++)
  18. for (x=0;x<=n; x++)
  19. {
  20. int t= x+(n+1)*y+(n+1)*(n+1)*z;
  21. point[t].x = x;
  22. point[t].y = y;
  23. point[t].z = z;
  24. point[t].dp = dp(n, x, y, z);
  25. }
  26. }
  27. int orth(point3 p0, point3 p1,point3 p2)
  28. {
  29. return ((p1.x-p0.x)*(p2.x-p0.x) + (p1.y-p0.y)*(p2.y-p0.y) + (p1.z-p0.z)*(p2.z-p0.z))==0;
  30. }
  31. void addp2(point3& r, point3 p0, point3 p1, point3 p2)
  32. {
  33. r.x=p1.x+p2.x-p0.x;
  34. r.y=p1.y+p2.y-p0.y;
  35. r.z=p1.z+p2.z-p0.z;
  36. }
  37. void addp3(point3& r, point3 p0, point3 p1, point3 p2, point3 p3)
  38. {
  39. r.x=p1.x+p2.x+p3.x-2*p0.x;
  40. r.y=p1.y+p2.y+p3.y-2*p0.y;
  41. r.z=p1.z+p2.z+p3.z-2*p0.z;
  42. }
  43. int inside(int n, point3 p)
  44. {
  45. return (p.x<=n)&&(p.x>=0)&&(p.y<=n)&&(p.y>=0)&&(p.z<=n)&&(p.z>=0);
  46. }
  47. long long calc(int n)
  48. {
  49. if (n < 1) return 0;
  50. if (n == 1) return 1;
  51. point3 t;
  52. long long c=0;
  53. init(n);
  54. int max=(n+1)*(n+1)*(n+1)-1;
  55. for (int i=0; i<=max-(n+1)*(n+1)-3; i ++)
  56. for (int j=i+1; j<=max-(n+1)*(n+1)-2; j ++)
  57. for (int k=j+1; k<=max-(n+1)*(n+1)-1; k ++)
  58. if (orth(point[i], point[j], point[k]))
  59. for (int m=k+1; m<=max; m ++)
  60. {
  61. if (orth(point[i], point[j], point[m]))
  62. if (orth(point[i], point[m], point[k]))
  63. {
  64. addp2(t, point[i], point[j], point[k]);
  65. if (inside(n, t))
  66. {
  67. addp2(t, point[i], point[m], point[k]);
  68. if (inside(n, t))
  69. {
  70. addp2(t, point[i], point[j], point[m]);
  71. if (inside(n, t))
  72. {
  73. addp3(t, point[i], point[j], point[k], point[m]);
  74. if (inside(n, t)) c++;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. return c;
  81. }
  82. int main( void )
  83. {
  84. int n;
  85. cout << "input: ";
  86. cin >> n;
  87. cout << endl;
  88. if (n > MAX) cout << "input is to BIG" << endl;
  89. cout << "total: " << calc(n);
  90. return 0;
  91. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-23 20:40 , Processed in 0.025070 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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