第十三届 ACMCCPC 吉林省赛 E. Stick War

    xiaoxiao2021-04-15  185

    ACM/CCPC 历届真题 题解目录

    Problem E. Stick War

    Time Limit: 1000ms Memory Limit: 512MB   Description The Stick Kingdom will start a war to the Hammer Kingdom! The power of the stick army is the number of 1 ∗ 1 grids made up of sticks. The king of Stick Kingdom would give you the grids he needed, and you should tell him the minimum number of sticks he needed. Note: it’s very difficult for sticks to stand up, so the grids must be made on a 2-D plane.   Input First line contains an integer T (1 ≤ T ≤ 10v) represents the number of test cases. For each test case: The first line contains an integer n (1 ≤ n ≤ 1 0 6 10^6 106) represents the number of grids the king needed.   Output For each test case, output a line contains an integer represents the minimum number of sticks the king needed.   Sample Input 4 1 2 3 4   Output 4 7 10 12   Hint

    题目大意:   如上图方式用木棍拼方块,给你方块的数量,求最少需要用多少根木棍?   分析:   根据题意,我们很容易发现,只有将小方块向大方块的形状上去拼,需要的木棍数量才是最少的。   那么我们就需要知道, n n n个小方块能拼成多大的大方块?答案是边长为 [ n ] [\sqrt{n}] [n ]的大方块("[]“代表向下取整)。   思路:   我们令 t = [ n ] t= [\sqrt{n}] t=[n ],而:   1. 边长为 t t t的大方块,需要 t × ( t + 1 ) × 2 t \times (t+1) \times 2 t×(t+1)×2根木棍拼成(自己证明)。   2. 边长为 t t t的大方块需要 t × t t \times t t×t个小方块。   注:这里 t = [ n ] t= [\sqrt{n}] t=[n ]的”[]"代表向下取整,也就是说, [ n ] × [ n ] [\sqrt{n}] \times [\sqrt{n}] [n ]×[n ]不一定等于 n n n。如: [ 5 ] = 2 , 2 × 2 = 4 , 即 [ 5 ] × [ 5 ] = 4 [\sqrt{5}] = 2, 2 \times 2 = 4,即[\sqrt{5}] \times [\sqrt{5}] = 4 [5 ]=22×2=4[5 ]×[5 ]=4。   我们令 v = n − t × t v = n- t \times t v=nt×t,即 n n n个小方块拼成边长为 t t t的大方块后,还多出 v v v个小方块。   那么多出来的小方块怎么算?我们不难看出,边长为 t t t的方块向边长为 t + 1 t+1 t+1的方块方向上去拼,只需要填充两条临边即可。如图:   根据上图,我们不难看出,多出一( v v v)个小方块,就要多两( v × 2 v \times 2 v×2)根木棍,且每条边的起点处需要三根木棍。那么规律就出来了:   一共两条边,边长为 t t t,每条边的第一个小方块需要三根木棍,即第 1 1 1个小方块和第 t + 1 t+1 t+1个小方块各需要在 v × 2 v \times 2 v×2的基础上加一根木棍。所以多余的小方块需要木棍数量公式为: v × 2 + ( v ≠ 0 ) + ( v > t ) v \times 2+(v \neq 0)+(v>t) v×2+(v̸=0)+(v>t)  其中 ( v ≠ 0 ) (v \neq 0) (v̸=0)代表存在第一个小方块; ( v > t ) (v > t) (v>t)代表存在第 t + 1 t+1 t+1个小方块。所以,代码如下:

    #include <iostream> #include <cmath> using namespace std; int t, n; int main() { scanf("%d", &t); while(t--) { scanf("%d", &n); int t = sqrt(n); //大方块边长t int v = n - t*t; //多v个小方块 int ans = t * (t+1) * 2; //大方块需要的木棍数量 ans += v * 2 + (v != 0) + (v > t); //加上v个小方块需要的木棍数量 printf("%d\n", ans); } return 0; }

    最新回复(0)