让我们来燃烧脑细胞吧~

题目描述: 目前我有一个正方体,边长为N,我以单位1为边长,将正方体分割成N*N*N个单位正方体,请问里面有多少对正方体公共点不大于2?
当N=1,有0对,当N=2,有16对,当N=3,有297对,给出关于N的公式。

题主关于第一个第二个第三个的答案是正确的,注意公共点不大于2,也就是说公共点允许0、1、2这三种情况,根据实际情况其实只需要满足方块之间没有公共面即可满足条件。
所以,下面给出我的推论过程:
N=1,显然,0对
N=2,形状如下图(丑点忍着看吧,ps纯手工画的)
图片说明
可以看到,由8个角上的小方块组成,那么我们开始数面,对于每个小方块来说,与其他小方块连接的面均是3,那么我们任意选定一个小方块,将该小方块和与该小方块面相接触的小方块排除的话,那么我们就会剩下2*2*2-(3 + 1)=4 也就是4个小方块,也就是说,剩下四个小方块与所选定的小方块之间是满足公共点不大于2的条件的,那么对于8各小方块,我们总共就有,4*8=32种,排除重复的(以A方块为基准的时候选择到了B方块,以B方块为基准的时候选择到了A方块,但是实际上,两个只能算一对)要除以2,所以,最终结果是 32/2=16
N=3,形状如下图(还是依旧那么丑)
图片说明
这种情况比较有意思,可以按照邻接的面的数量分成四类小方块,
第一类:8个角上的,有8个小方块,每个小方块邻接的面数为3,也就是说,这类小方块将会挖走4个小方块(自己一个,邻接的三个),剩下的与它全部满足条件,按照总数为3^3=27的话,那么满足条件的小方块为 27-4=23个,好的,这个结果先放着
第二类:12条边上的,有12个小方块,每个小方块邻接的面数为4,这类小方块将会挖走5个小方块(自己一个,邻接的四个),剩下的与它全部满足条件,那么满足条件的小方块为 27-5=22个,这个结果也放着
第三类:6个面心(在外面能看到的不属于边也不属于角上的),共6个,每个小方块邻接的面数为5,这类小方块将会挖走6个小方块,同理满足条件的小方块数为 27-6=21个
第四类:中心处(其实就是在外面看不到的小方块),共1个,每个小方块邻接的面数为6,这类小方块将会挖走7个小方块,与之满足条件的小方块个数为27-7=20个。
好的,有了这四类小方块,对应的个数以及每类小方块所挖走的方块的数量之后,那么我们就可以按照N=2时候的思路,列出如下的式子:
(8*23 + 12*22+6*21+20)/2=297
式子可以整理一下:
(8*(3^3-4)+12*1*(3^3-5)+6*(1^2)*(3^3-6)+(1^3)*(3^3-7))/2=297

N=4,我就不画图了,大家可以脑洞一下。
这种情况下,小方块实际上还是分为4类,这4类和在N=3的时候给出的一样,但是这个数量不一样,我直接给出各个类对应的数量:
第一类:8个角,8个小方块
第二类:12条边,每边2个小方块,所以12*2 = 24个
第三类:6个面,每面4个,所以 6 * (2^2)=24 个
第四类:4*4*4-8-24 - 24 = 8 个,排除法嘛,其实就是 (2^3)=8 个,
所以嘛,和N=3的时候也一样,列出的式子就是:
(8*(4^3-4)+12*2*(4^3-5)+6*(2^2)*(4^3-6)+(2^3)*(4^3-7))/2=1 872

N=5类推。。。。。
所以归类就出来了:
N=1 满足条件的对数为:0
N>1 满足条件的对数为:(8*(N^3-4)+12*(N-2)*(N^3-5)+6*((N-2)^2)*(N^3-6)+(N-2)^3*(N^3-7))/2

这道题就当娱乐,在没事的时候来想想,锻炼自己的思维能力。希望有人能给出思考过程。

我觉得你的答案本身都有问题

一个正方体,边长N,那么它有N^3个正方体,能组成(N^3)* (N^3 - 1) / 2 个正方体对。
排除两个相连的正方体对,(N*(N-1)*2)*N*3
结果应该是(N^3)* (N^3 - 1) / 2 - (N*(N-1)*2)*N*3
当N=2是8*7/2-(2*2*2*3)=28-24=4。

换言之,在一个N为2的立方体内,只有对角线上的四对才只有一个公用定点,其它都有4个。所以结果根本不是16。
至于怎么写程序,我已经给你公式了。

我搞清楚了。我之前的思路是对的,只是在计算相邻面的时候有重复,加上一个除2就对了。

(N^3)* (N^3 - 1) / 2 - (N*(N-1)*2)*N*3
->
(N^3)* (N^3 - 1) / 2 - (N*(N-1)*2)*N*3/2 <-加上

 #include <stdio.h>
int p(int x, int n)
{
    int r = 1;
    for(int i =0; i < n;i++)
        r *= x;
    return r;
}
int main()
{
    for (int N=1; N<10;N++)
    printf("%d, %d\n", N, p(N,3)* (p(N,3) - 1) / 2 -(N*(N-1)*2)*N*3/2);
    return 0;
}

1, 0
2, 16
3, 297
4, 1872
5, 7450
6, 22680
7, 57771
8, 129472
9, 263412
Press any key to continue

我的公式更简单,而且不需要对N=1分类讨论。

再简化下

 (N^3)* (N^3 - 1) / 2 - N*(N-1)*N*3

我再清楚地解释下我的公式,分为两部分,一个是总共的对,一个是需要排除两者相连的对。
(N^3)* (N^3 - 1) / 2
这是前半部分。这个不解释了。
N*(N-1)*N*3
这里我们需要找出两个连着的对,
我们看一个方向,比如从上往下一个方向,1 2组合 2 3 组合直到N-1 N组合,一共是N-1个组合,一共是N列,一共又有N层,所以一个方向是N*(N-1)*N
一个是三个方向,所以最后乘以3

之前的错误是每个面我算了横行和纵行,但是它的侧面的纵行其实和这里的纵行是重复计算了。所以每个面只要算一个方向就可以了。

我在这里感谢caozhy和林深两位大神的详细解答,本次答案采取林深的解答,毕竟人家给出的答案最详细最早同时给出了公式(嘛~不过没化简)
但是caozhy给出了最终的公式,值得肯定。以后会有更多烧脑娱乐系列,希望大家来玩!