您的位置:首页 > 其它

第14届浙江大学程序设计竞赛 B. Continuous Login (ZOJ 3768)

2014-04-06 22:54 295 查看
【来源】

ZOJ 3768 Continuous Login

【分析】

本来毫无头绪,深度优先搜索?穷举?复杂度太高了……然后网上搜了一下大神们的解法,得到了一个重要提示:分出的块数不会超过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呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  zoj
相关文章推荐