2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(E: Half-consecutive Numbers(强大规律思维题+打表))

在这里插入图片描述在这里插入图片描述
题意很很简单吧!!!
但是一看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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值