题意很很简单吧!!!
但是一看1e16,马上就知道应该去找什么规律之类的了;
打了一下表可以发现1,8,49,288,…出现频率比较高;
这里简单的打表只需要跑个1e4,用两个for就可以看出来滴;
for(ll i=1;i<=1e4;i++){
for(ll j=i;j<=1e3;j++){
ll t=i*(i+1)/2;
if(sqrt(t)-(ll)sqrt(t)<=1e-6){
printf("%lld,",i);break;
}
}
}
然后可以根据数学知识想一想;
i*(i+1)/2是个完全平方数,那么肯定和因子有什么关系;
然后可以知道这两种情况:
1.sqrt(i)为整数,sqrt((i+1)/2)为整数;
2.sqrt(i/2)为整数,sqrt((i+1))为整数;
只有这两种情况才能构成一个完全平方数;
但是我感觉没什么用的哇,知道这个?
然后参考了大佬的题解,自己恍然大悟,自愧不如QAQ;
大佬的规律是这样滴:
因为可以找出来r对应的tr,并且分解tr,可以看看规律,发现这个问题:
下一个的a是上一个的a+b的值,然后b的值 就需要分a的奇偶性,如果当前a为偶数,那么b=sqrt(aa2+1);
如果当前a为奇数那么b=sqrt(aa2-1);
这个规律真的难发现;
而且还需要找到和r的关系;所以序号r的值为:
1.a为偶数时,r=aa2;
2.a为奇数时,r=aa2-1;
所以这段规律就很神奇了;
知道了这个规律,然后就可以打表求出最大对应的r值,只需要求到1e16多点点就可以了;
所以根据这个规律就可以打表了:
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll sum[100];
void init(){
sum[0]=1;
ll a,b,c;
a=b=1;
for(int i=1;i<=20;i++){
if(i%2){
c=(a+b)*(a+b)*2;
sum[i]=c;
a=a+b;
b=sqrt(c+1);
}else{
c=(a+b)*(a+b)*2;
sum[i]=c-1;
a=a+b;
b=sqrt(c-1);
}
}
// for(int i=1;i<=20;i++){
// cout<<sum[i]<<endl;
// }
}
int main()
{
init();
scanf("%d",&T);
int g=1;
while(T--){
ll N;
scanf("%lld",&N);
int f=0;
for(int i=0;i<=20;i++){//找是否有第一个大于N的值
if(sum[i]>=N){
printf("Case #%d: %lld\n",g++,sum[i]);
f=1;
break;
}
}
if(!f){
printf("Case #%d: -1",g++);
}
}
return 0;
}