Chieh's Blog

Because Of Coding

ZOJ Problem Set - 3768 Continuous Login

Chieh posted @ 2015年7月23日 13:47 in ZOJ , 369 阅读

飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5231

题意:给你个数n,求最少的数,假设为a1...ak, 1+2+3...+a1+1+2+3+..a2.....+ak=n

分析:这题乍一看没有任何想法,但是我们可以暴力搜下,发现前100000最多只有3个,那么我们可以直接猜测最多只有三个,那么就可以开始搞了,先求出从1+2+。。。k>=123456789最大的n是多少,加入只有一个,直接二分查找,如果找不到,那么就尝试2个的,两个的话可以用夹逼定理,假设左边为1,右边为k,如果a1+ak>n那么就是太大了,r--,如果是<n,那么就是太小了l++,等于的话就说明2个可以,如果2个不可以,那么就三个,第一个数可以枚举,后面两个数可以用夹逼寻找,最后啪啪啪就可以AC了

/*
Author:Chieh
Grow up happy
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#define LL long long
using namespace std;
int ai[16000];
int T,n;
int st;
void init()
{
    scanf("%d",&n);
}
int l,r;
bool Brsearch(int p)
{
     l=1;
     r=st-1;
    while(l<=r)
    {
        int ok=ai[l]+ai[r];
        if(ok==p)return 1;
        if(ok<p)l++;
        else r--;
    }
    return 0;

}
void play()
{
    int pos=lower_bound(ai+1,ai+st,n)-ai;
    if(ai[pos]==n)
    {
        printf("%d\n",pos);
        return;
    }
    if(Brsearch(n)){
        printf("%d %d\n",l,r);
        return;
    }
    for(int i=1;i<=n;i++){
        if(n>=ai[i]&&Brsearch(n-ai[i])){
            printf("%d %d %d\n",i,l,r);
            return;
        }
    }
}
int main()
{
    st=1;
    LL now=0;
    while(now<=123456789)
    {
        now+=st;
        ai[st]=now;
        st++;

    }

    scanf("%d",&T);
    while(T--)
    {
        init();
        play();
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter