题目大意
定义一个长度为 n n n数列 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an为合法的序列,对于 ∀ i ∈ { 1 , 2 , ⋯ , n } \forall i\in \{1,2,\cdots,n\} ∀i∈{1,2,⋯,n}其需要满足如下条件之一:
- a i = 1 a_i=1 ai=1
- ∃ j ∈ { 1 , 2 , ⋯ , n } \exists j\in \{1,2,\cdots,n\} ∃j∈{1,2,⋯,n}使得 a j = a i − 2 a_j=a_i -2 aj=ai−2
- ∃ j ∈ { 1 , 2 , ⋯ , n } \exists j\in \{1,2,\cdots,n\} ∃j∈{1,2,⋯,n}使得 a j = a i − 1 a_j=a_i -1 aj=ai−1
现在给出 S S S需要任一输出长度最短的合法序列且满足 ∑ i = 1 n a i = S \displaystyle\sum_{i=1}^n a_i = S i=1∑nai=S
时间限制
1s
数据范围
s ≤ 5000 s\le 5000 s≤5000
题解
和一定,需要长度最短,那么最优的方案就是
a
i
a_i
ai尽可能的大。
根据合法序列的定义,就可以知道
a
i
a_i
ai最大的情况如下:
1
,
3
,
5
,
7
,
⋯
1,3,5,7,\cdots
1,3,5,7,⋯
那么答案就是 1 , 3 , 5 , ⋯ , ( 2 × k − 1 ) , S − ∑ i = 1 k ( 2 × i − 1 ) 1,3,5,\cdots,(2\times k - 1),S-\displaystyle\sum_{i=1}^k (2\times i - 1) 1,3,5,⋯,(2×k−1),S−i=1∑k(2×i−1)
Code
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#define G getchar
#define ll long long
using namespace std;
ll read()
{
char ch;
for(ch = G();(ch < '0' || ch > '9') && ch != '-';ch = G());
ll n = 0 , w;
if (ch == '-')
{
w = -1;
ch = G();
} else w = 1;
for(;'0' <= ch && ch <= '9';ch = G())n = (n<<1)+(n<<3)+ch-48;
return n * w;
}
const int N = 100005;
int n , m , pos , ans;
int main()
{
//freopen("f.in","r",stdin);
//freopen("f.out","w",stdout);
for (int T = read() ; T ; T--)
{
n = read();
pos = -1;
ans = m = 0;
for ( ; m < n ;)
{
pos = pos + 2;
m = m + pos;
ans ++;
}
printf("%d\n", ans);
}
return 0;
}