在这道题目上我充分的认识到了专注的重要性,下午做题心思一直不在线,一直想着各种事情,想要把各种事情做好,除非是能力特别高的,不然到头来大概率是所有的事情都做不好,专注下啊啊啊啊啊啊,所有的决策不一定都是最优的,也不一定是最坏的,慢慢的看着来吧。
题目地址
题目大意:我还是写的详细点吧,毕竟折磨了我好久的。
上图是题目中的楼梯的样式,都是由一个一个的小正方形组成的,并且都是第一行1个,第二行2个……等等。题目的问题是给你这些小正方形的数目个数,求利用这些小正方形组成的nice型阶梯的数目是多少(小正方形可以不用完),nice型阶梯是指对于上图这种
n
∗
n
n * n
n∗n 的阶梯来说,要求利用不超过
n
n
n 个正方形(不是小正方形)填满这个 阶梯,并且小正方形不可以重复。
思路:首先我们需要先证明对于n个阶梯来说,填满最少需要n个正方形,因为我们的侧边的每个小正方形都不可能公用一个大正方形,侧边的小正方形有n个,所以我们必须需要n个正方形,我真的好菜。
那么我们就有思路了,必须使得每个小正方形包括在大的正方形里边,想到这里应该就有我们的贪心做法了,每次我们取阶梯左上-右下对角线,取出最大的正方形,将阶梯分为两个阶梯,这里需要保证
n
n
n是奇数,并且
n
/
2
n / 2
n/2也是奇数 并且
n
/
2
/
2
n / 2 / 2
n/2/2也是奇数,直到
n
=
=
1
n == 1
n==1为止。
代码:
#include <iostream>
#include <cstring>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 50;
long long a[N], sum[N];
int main()
{
int T; scanf ("%d", &T);
while (T --)
{
long long x, a = 1; scanf ("%lld", &x);
int ans = 0;
while (x >= (a * (a + 1)) / 2)
{
x -= a * (a + 1) /2;
a = a + a + 1;
ans ++;
}
cout << ans << endl;
}
return 0;
}