HDU 4342 History repeat itself 2012 Multi-University Training Contest 5

本文探讨了一个寻找特定序列中非平方数的问题,并提供了两种解决方案:一种是通过预处理建立表来查找,另一种是直接使用公式计算。详细介绍了如何通过数学公式和预处理方法来解决该问题,包括序列的生成、非平方数的查找以及计算其对应结果的过程。
摘要由CSDN通过智能技术生成

题意:T个测试数据

下面给出n ,

从自然数( 从1开始 )中找到第 n 个不能开平方的数M  以及 M在图中公式求出的结果

1  2  3  4  5  6  7   8  9  10  11  12  13  14  15  16  17  18

    1  2       3  4  5  6        7     8     9  10  11  12         13   14

简单的说就是给出下面序列,求上面对应的数

方案一是比赛打的,后来发现做复杂了,不过按比赛时间来算,20分钟打个表比推公式可能好想点

 

方案一:预处理

思路:这里N最大是2^31 开平方后就是 46340 ,5位数还能接受,所以打表存在set里

首先求出M,可以把 每个平方数+1对应的n存到set中

也就是存入了

2  10  17

1   7    13

tnode[1]={2,1} ,tnode[2]={10,7}

可以得到 tnode[i]={ i^2 +1, i^2 - i }  i^2 - i 就是i^2这个数减去其中所有的平方数

sum[i] 表示i^2 这个数在公式中求得的结果

mark:

#include<stdio.h>
#include<math.h>
#include<set>
using namespace std;
#define N 46340
#define ll __int64
struct node{
	ll num,xu;//num表示xu对应的非平方数 
	bool operator < (const node & a) const{
		return a.xu>xu;
	}
}tnode;
set<node>ss;
set<node>::iterator p;
ll sum[N],num,temp,i;
int main(){
	sum[0]=0;	ss.clear();
	for(i=1;i<N;i++)
	{
		sum[i]=(i*i-(i-1)*(i-1)-1)*(i-1)+sum[i-1]+i;//求和 M
		tnode.num=i*i+1;
		tnode.xu=tnode.num-i;
		ss.insert(tnode);
	}
	int T;scanf("%d",&T);
	while(T--){
		scanf("%I64d",&num);
		//temp是第一个答案,也就是“上面”的序列
		tnode.xu=num;
		p=ss.upper_bound(tnode);
		if(p->xu==num)temp=tnode.num;
		else
		{
			p--;
			temp=num-p->xu+p->num;
		}
		ll sq=sqrt((double)temp);
		printf("%I64d %I64d\n",temp,sum[sq]+(temp-sq*sq)*sq);
	}
	return 0;
}


 

 

方案二:

公式代入

(1+sqrt(1+4*a))/2;必需对这个数上取整,然后减一就是n了。
然后第a个非平方数就是 n*n+(a-n*n+n)=a+n

之后就是求另一个式子的值了,首先求1~n*n-1求和:
(2*n-1)*(n-1)对它从2到n求和得到:n*(n+1)*(2*n+1)/3-3*n*(n-1)/2+n;
之后加上 (n+a-n*n+1)*n;

 

#include<stdio.h>
#include<math.h>
int main()
{
    int T;scanf("%d",&T);
    __int64 n,a;
    while(T--)
    {
        scanf("%I64d",&a);
        n=ceil((1+sqrt((double)(1+4*a)))/2)-1;
        printf("%I64d %I64d\n",n+a,n*(n+1)*(2*n+1)/3-3*(n+1)*n/2+n+(n+a-n*n+1)*n);
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值