2021-08-03

本文探讨了一个三维空间填充问题,目标是在n*n*n的空间内放置1*1*1的立方体,使得从三个方向观察都能形成正方形,并计算了在特定条件下最小与最大花费的数学模型。

Banzhuan
题目链接
题意:给你一个n∗n∗nn*n*nnnn的空间,现在你需要在里面放多个1∗1∗11*1*1111的立方体,使得从上面,前面,侧面看过去都是一个正方形,在(x,y,z)(x,y,z)(x,y,z)处放入立方体会产生花费x∗y2∗zx*y^2*zxy2z,当你放入位置的下方(x,y,z−1)(x,y,z-1)(x,y,z1)处是空的,立方体就会下坠至(x1,y1,z1+1)(x_1,y_1,z_1+1)(x1,y1,z1+1)处,当(x1,y1,z1)(x_1,y_1,z_1)(x1,y1,z1)处已经有立方体时,问未达成要求最小花费和最大花费分别为多少

解析:
①最大花费:首先是要全部填满,即放入n∗n∗nn*n*nnnn个立方体,当放入n∗n∗nn*n*nnnn个立方体时,x,y没法为花费最大化做出贡献,我们只能在z的大小做文章:当下方是空的时候,立方体会下落,我们可以使每一个立方体的初始z值都为n,此时使得花费最大,此时花费为
n∗n∗∑x=1nx∗∑y=1ny2n*n*\sum_{x=1}^{n}x*\sum_{y=1}^{n}y^2nnx=1nxy=1ny2
②最小花费:为了从上向下看能是个n∗nn*nnn正方形,最下层是必须的铺满的,为从前看n∗nn*nnn的正方形,任意的y处都必须有n个立方体都叠在一起,花费计算公式为x∗y2∗zx*y^2*zxy2z,y和z是固定的,为使花费最小,我们应取x=1,从左边看和从前面看同理,取y=1,同时发现(1,1,z)(1,1,z)(1,1,z)处不堆立方体也可达到效果,故最小花费为:
∑x=1nx∑y=1ny2+∑z=2nz∑y=2ny2+∑x=2nx∑z=2nz\sum_{x=1}^{n}x\sum_{y=1}^{n}y^2+\sum_{z=2}^{n}z\sum_{y=2}^{n}y^2+\sum_{x=2}^{n}x\sum_{z=2}^{n}zx=1nxy=1ny2+z=2nzy=2ny2+x=2nxz=2nz

AcCode:

#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>

#define int long long
#define ll __int128

#define eps 0.0000001

const int N = 1e6 + 100;
const int mod = 1e9+7;

#define T long long 
inline T max(T a,T b){return (a>b)?a:b;}
inline T min(T a,T b){return (a<b)?a:b;}

inline int quick_pow(int a,int b){
    int ans=1;
    a%=mod;
    while(b){
        if(b&1) ans = ans*a%mod;
        a = a*a%mod;
        b>>=1;
    }
    return ans;
}

int mul(int a,int b){
    int ans=0;
    while(b){
        if(b&1) ans = (ans+a)%mod;
        a = (a+a)%mod;
        b>>=1;
    }
    return ans;
}

signed main() {
    int t; scanf("%lld", &t);
    while (t--) {
        int n;scanf("%lld",&n);
        int max1 = mul(n,n);
        int max2 = mul(n,n+1)*quick_pow(2,mod-2)%mod;
        int max3 = mul(n,mul(n+1,2ll*n+1))*quick_pow(6,mod-2)%mod;
        int maxans = mul(max1,mul(max2,max3));
        int minans = mul(max2,max3);
        int min2 = mul(n+2,n-1)*quick_pow(2,mod-2)%mod;
        min2 = mul(min2,min2);
        minans = (minans+min2)%mod;
        minans = minans+mul(mul(n+2,n-1)*quick_pow(2,mod-2)%mod,(max3-1+mod)%mod);
        printf("%lld\n%lld\n",minans%mod,maxans );
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值