第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 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呢?
相关文章推荐
- 第14届浙江大学程序设计竞赛 A. Elevator(ZOJ 3767)
- 第14届浙江大学程序设计竞赛 D. Ranking System(ZOJ 3770)
- 第14届浙江大学程序设计竞赛 I. ?(>_o)! (ZOJ 3775)
- ZOJ 3770 : Ranking System (第14届浙江大学程序设计竞赛 D) - 结构体排序,vector
- ZOJ 3944-People Counting【模拟】(2016浙江省大学生程序设计竞赛)
- zoj 3602 Count the Trees 二叉树HASH 浙江省第9届大学生程序设计竞赛 第三题
- ZOJ 3946-Highway Project【最短路的应用】(2016浙江省大学生程序设计竞赛)
- ZOJ 3936-Apples and Ideas【模拟】(2016浙江省大学生程序设计竞赛)
- ZOJ 3938-Defuse the Bomb【模拟,题看着挺长】(2016浙江省大学生程序设计竞赛)
- ZOJ 3947-Very Happy Great BG【模拟】(2016浙江省大学生程序设计竞赛)
- 浙江大学第13届程序设计竞赛总结
- 2017广东工业大学程序设计竞赛决赛-占点游戏
- 2017广东工业大学程序设计竞赛决赛-Problem H: tmk买礼物
- ACM Red and Black(挑战程序设计竞赛)
- 湖南省第七届大学生计算机程序设计竞赛 多连块拼图 (模拟)
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 G(2331) Great Atm(二进制)(思路)
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 hrbust 2331 Great Atm
- 第三届H-star 程序设计竞赛决赛题解
- ACM Seven Puzzle(挑战程序设计竞赛)
- SDUT 2165 Crack Mathmen(快速幂)山东省第二届ACM大学生程序设计竞赛