2014 Super Training #7 B Continuous Login --二分
原题:ZOJ 3768 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3768
一个结论:一个正整数总能用不超过三个前n项相加表示。
先找一个的,在找两个,三个的,二分找,用lower_bound函数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
#define N 16007
int sum[N];
void init()
{
sum[0] = 0;
for(int i=1;i<16000;i++)
sum[i] = sum[i-1] + i;
}
int main()
{
int t,n,i,j;
init();
int a,b;
int x,y,z;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int flag = 0;
int t = lower_bound(sum,sum+16000,n)-sum;
if(sum[t] == n)
{
printf("%d\n",t);
continue;
}
for(i=t;i&&2*sum[i]>=n;i--)
{
if(flag == 2)
break;
int lef = n-sum[i];
int t2 = lower_bound(sum,sum+16000,lef)-sum;
for(j=t2;j&&sum[i]+sum[j]*2>=n;j--)
{
if(flag == 2)
break;
if(sum[i]+sum[j]==n)
{
flag = 2;
a = i,b = j;
break;
}
else if(flag == 3)
break;
else if(sum[i]+sum[j]<n)
{
int lef2 = n-sum[i]-sum[j];
int t3 = lower_bound(sum,sum+16000,lef2)-sum;
if(sum[t3] == lef2)
{
flag = 3;
x = i,y = j,z = t3;
break;
}
}
}
}
if(flag == 2)
printf("%d %d\n",a,b);
else if(flag == 3)
printf("%d %d %d\n",x,y,z);
}
return 0;
}
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com