E: Half-consecutive Numbers time
limit 2000ms memory limit 131072KB
The numbers 1, 3, 6, 10, 15, 21, 28, 36, 45 and t = i(i +1), are called halfconsecutive. For given N, find the smallest r which is no smaller than N such that t is square.
i 2
1
r
Input Format The input contains multiple test cases. The first line of a multiple input is an integer T followed by T input lines. Each line contains an integer N (1 ≤ N ≤ 10 ). Output Format For each test case, output the case number first. Then for given N, output the smallest r. If this half-consecutive number does not exist, output −1. Sample Input
4 1 2 9 50
Sample Output
Case #1: 1 Case #2: 8 Case #3: 49 Case #4: 288
【题意】:
找到这样的i,使得i*(i+1)=2*k^2。其中k为任意整数,i为整数。
然后输入n,输出不小于n的这个i。
【解析】:
先找到了规律,对于所有满足条件的i,对应的k,排成一个数列,那么数列满足:
F[1]=1;
F[2]=8;
F[t]=F[t-1]*6 - F[i-2];
把这个F数组全打表出来,总共就几十个。再由他解出i;
说实话这个规律看了好久才看出来。。。。。
提前打表出这些满足条件的i存起来。
【代码】:
AC代码:
#include <stdio.h>
long long a[50]={
1,
8,
49,
288,
1681,
9800,
57121,
332928,
1940449,
11309768,
65918161,
384199200,
2239277041,
13051463048,
76069501249,
443365544448,
2584123765441,
15061377048200,
87784138523761,
511643454094368,
2982076586042449,
17380816062160328,
-1
};
int main()
{
int T,r=1;
long long n;
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
int i;
for(i=0;a[i]!=-1;i++)
{
if(a[i]>=n)
break;
}
printf("Case #%d: %lld\n",r++,a[i]);
}
return 0;
}
打表代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const ll MAX=1e17;
const int M=1e8;//亿进制
typedef queue<ll> BigNum;
BigNum getnum(ll num)
{
BigNum q;
while(num)
{
q.push(num%M);
num/=M;
}
return q;
}
void out(BigNum q)//递归输出队列大数
{
if(q.size()==1){
printf("%lld",q.front());
return;
}
ll num=q.front(); q.pop();
out(q);
printf("%08lld",num);
}
BigNum operator+(BigNum q1,BigNum q2)//加
{
BigNum sum;
ll flag=0;//进位
while(!q1.empty()||!q2.empty())
{
int num1=0,num2=0;
if(!q1.empty()){
num1=q1.front();
q1.pop();
}
if(!q2.empty()){
num2=q2.front();
q2.pop();
}
sum.push(flag+(num1+num2)%M);
flag=(num1+num2)/M;
}
if(flag)
sum.push(flag);
return sum;
}
BigNum operator*(BigNum q1,BigNum q2)//大数乘大数
{
BigNum ans;
ll k=0;
while(!q2.empty())//模拟手工运算
{
ll n=q2.front(); q2.pop();
BigNum temp,re=q1;//re暂存q1
for(int i=0;i<k;i++)
temp.push(0); //后置0
k++;
ll flag=0;//进位
while(!re.empty())
{
temp.push(flag+(n*re.front())%M);
flag=(n*re.front())/M;
re.pop();
}
if(flag)
temp.push(flag);
ans=ans+temp;//累加
}
return ans;
}
BigNum operator/(BigNum q,ll m)//大数q整除以m(注,m+M<ll)
{
stack<ll> s,ans;
while(!q.empty()){ //压入栈
s.push(q.front());
q.pop();
}
ll flag=0;//flag移位
while(!s.empty())
{
ll top=s.top()+flag*M;
if(top>=m||!ans.empty())//排除最高位是0
ans.push(top/m);
flag=top%m;
s.pop();
}//最后的flag为余数
while(!ans.empty()){
q.push(ans.top());
ans.pop();
}
if(q.empty())q.push(0);
return q;
}
int mycmp(BigNum q1,BigNum q2)
{
if(q1.size()==q2.size())
{
ll num1,num2,flag=0;
while(!q1.empty())
{
num1=q1.front();q1.pop();
num2=q2.front();q2.pop();
if(num1!=num2)
flag=num1-num2;
}
return flag;
}
return q1.size()-q2.size();
}
BigNum operator*(BigNum q1,ll m)//大数乘int m
{
BigNum ans;
ll flag=0;//进位
while(!q1.empty())
{
ll num=q1.front();
q1.pop();
ans.push((m*num+flag)%M);
flag=(m*num+flag)/M;
}
if(flag)
ans.push(flag);
return ans;
}
BigNum operator-(BigNum q1,BigNum q2)//q1-q2(注!仅限q1>q2)
{
BigNum less;
if(mycmp(q1,q2)<0){
BigNum a=q1;q1=q2;q2=a;
}
while(!q1.empty())
{
int num1=0,num2=0;
num1=q1.front();
q1.pop();
if(!q2.empty()){
num2=q2.front();
q2.pop();
}
if(num1<num2){
q1.front()-=1;
num1+=M;//从q1高位借1,当M
}
less.push(num1-num2);
}
return less;
}
BigNum f(BigNum i)
{
return i*i+i;
}
int main()
{
ll ans=0;
BigNum F[50];
F[0]=getnum(0);
F[1]=getnum(1);
for(int i=2;i<40;i++)
{
F[i]=F[i-1]*6-F[i-2];
}
for(int i=1;i<40;i++)
{
BigNum k=F[i]*F[i];
BigNum l=getnum(1),r=getnum(100000000000000000);
while(mycmp(l,r)<0)//二分查找解i
{
BigNum mid=(l+r)/2;
if(mycmp(f(mid),k*2)>=0)
r=mid;
else l=mid+getnum(1);
}
if(mycmp(f(l),k*2)==0)
{
ans++;
out(l);
printf(",\n");
}
}
printf("%lld\n",ans);
}