第十三届 ACM/CCPC 吉林省赛 E. Stick War

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;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值