【来源】
【分析】
本来毫无头绪,深度优先搜索?穷举?复杂度太高了……然后网上搜了一下大神们的解法,得到了一个重要提示:分出的块数不会超过3。于是就愉快地分情况讨论,充分利用夹逼原理求出对应的值……
【源码】
#include <iostream>
#include <cmath>
using namespace std;
int getupperindex(int n)
{
return sqrt(n * 2) + 1;
}
int main()
{
int table[100001];
table[0] = 0;
for (int i = 1; i < 100001; ++i){
table[i] = table[i - 1] + i;
}
int T;
cin >> T;
while (T--){
int N;
cin >> N;
int flag = 0;
int upperIndex = getupperindex(N);
if (table[upperIndex] == N){
flag = 1;
cout << upperIndex << endl;
}
else if (table[upperIndex - 1] == N){
flag = 1;
cout << upperIndex - 1 << endl;
}
else{
int i;
for (i = upperIndex; i > 0 && !flag; --i){
if (table[i] < N){
int remain = N - table[i];
if (table[getupperindex(remain)] == remain){
flag = 1;
cout << i << " " << getupperindex(remain) << endl;
}
else if (table[getupperindex(remain) - 1] == remain){
flag = 1;
cout << i << " " << getupperindex(remain) - 1 << endl;
}
}
}
if (i == 0){
for (int ii = upperIndex; ii > 0 && !flag; --ii){
if (table[ii] < N){
int upj = getupperindex(N - table[ii]);
for (int j = upj; j > 0 && !flag; --j){
int remain = N - table[ii] - table[j];
if (remain > 0){
if (table[getupperindex(remain)] == remain){
flag = 1;
cout << ii << " " << j << " " << getupperindex(remain) << endl;
}
else if (table[getupperindex(remain) - 1] == remain){
flag = 1;
cout << ii << " " << j << " " << getupperindex(remain) - 1 << endl;
}
}
}
}
}
}
}
}
//system("pause");
return 0;
}
【点评】
如何证明分出的块数不超过3呢?