Board Moves CodeForces - 1353C(数学)

题意:

有一个 n×n 的矩阵(n 为奇数),每个矩阵单元有一个物品,每次操作你可将一个单元里的一个物品移动到该单元周围的八个单元里,问最后只有一个单元有物品的情况下,最少要多少次操作?

题目:

You are given a board of size n×n, where n is odd (not divisible by 2). Initially, each cell of the board contains one figure.

In one move, you can select exactly one figure presented in some cell and move it to one of the cells sharing a side or a corner with the current cell, i.e. from the cell (i,j) you can move the figure to cells:

(i−1,j−1);
(i−1,j);
(i−1,j+1);
(i,j−1);
(i,j+1);
(i+1,j−1);
(i+1,j);
(i+1,j+1);
Of course, you can not move figures to cells out of the board. It is allowed that after a move there will be several figures in one cell.

Your task is to find the minimum number of moves needed to get all the figures into one cell (i.e. n2−1 cells should contain 0 figures and one cell should contain n2 figures).

You have to answer t independent test cases.

Input

The first line of the input contains one integer t (1≤t≤200) — the number of test cases. Then t test cases follow.

The only line of the test case contains one integer n (1≤n<5⋅105) — the size of the board. It is guaranteed that n is odd (not divisible by 2).

It is guaranteed that the sum of n over all test cases does not exceed 5⋅105 (∑n≤5⋅105).

Output

For each test case print the answer — the minimum number of moves needed to get all the figures into one cell.

Example

Input

3
1
5
499993

Output

0
40
41664916690999888

分析(1):

找规律。可以看到正方形的每一个“圈”到中心的最小距离都是一样的(数一下就能发现规律)。然后把整个正方形分成八个小三角形+八条线或者直接按照圈来统计都行。

AC代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int t;
ll n,ans;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%lld",&n);
        for(ll i=2; i<=n/2+1; i++)
            ans+=(i-2)*(i-1);
        ans*=8;
        for(ll i=1; i<=n/2+1; i++)
            ans+=(i-1)*8;
        printf("%lld\n",ans);
    }
    return 0;
}

分析(二)

我们可以将所有物品最终都汇聚到矩阵的中心的单元格,那么以此为中心,他周围的第一圈的单元格的物品只需要一步就可以,第二圈就需要两步,以此类推。
  那么我们可以预处理出每一圈的单元格的数量,乘以他对应的步数,再求和即可。

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
typedef long long ll;
int f[N];
int main()
{
    f[0] = 0;
    for(int i = 1; i < N; i ++)
        f[i] = f[i - 1] + 8;
    int t;
    cin >> t;
    while(t --)
    {
        ll n;
        cin >> n;
        n = n * n - 1;
        ll ans = 0;
        for(int i = 1; ; i ++)
        {
            if(n >= f[i])
            {
                n -= f[i];
                ans += 1ll * i * f[i];
            }
            else
                break;
        }
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zeng_jun_yv/article/details/106268536