POJ1019 NumberSequence 【数学公式转化题】

这题也是一看感觉自己能做,就拿出笔和纸开始写写画画了,写的也蛮爽(下午1点到晚上8点,,,),其实,,,也就俩方程的事情。。。但是中间出了个逗比错误,10+11+12+...+99算成了(1+90)*90/2(找出这个错误真心不容易,现学了点linuxshell知识,也正好写了写相关的脚本,比如对拍脚本,运行脚本,挺好的)

这个错误也是奇葩,,前7000个竟然都没错,,真是 奇葩~

感觉数学题还是要做慢点,尤其是写完一个重要的东西,检验一下,,,错了就毙掉了,很花时间,在代码量还算少的时候就调试好

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
long long Fsave[99999];
long long fsave[99999];
char aint[59999];
inline long long  g(long long  n)//f函数的一部分,f函数是1234567891011...到每个数有几个数位f=g(n)+xn
{
    long long  tens=1;
    for(long long  i=0;i<n-1;i++)
    {
        tens*=10;
    }
    return (1-tens)/9-tens+n;
}
inline long long  getn(long long  x)//获得一个10进制数是几位数
{
    long long  co=0;
    while(x)
    {
        x/=10;
        co++;
    }
    return co;
}
inline long long  F(long long  x,long long  n)//1121231234最终序列的,到每个数而言有几个数位
{
    long long  sum=0;
    long long  tenPow=1;
    for(long long  i=1;i<=n-1;i++)
    {
        sum+=9*tenPow*g(i)+(tenPow+tenPow*10-1)*9*tenPow/2*i;
        tenPow*=10;
    }
    //cout<<"sum:"<<sum<<endl;
    n>=2?tenPow:tenPow=1;
    sum+=(x-tenPow+1)*g(n)+n*(tenPow+x)*(x-tenPow+1)/2;
    //cout<<tenPow<<endl;
    //cout<<n*(tenPow+x)*(x-tenPow+1)/2<<endl;
    return sum;
}
inline int binsearch(long long x,long long* A)从A中找出x的位置,夹在中间则取左边
{
    int L=0,R=104000;
    int mid=(L+R)>>1;
    while(L<R)
    {
        if(A[mid]>x)
            R=mid;
        if(A[mid]<x)
            L=mid+1;
        if(A[mid]==x)
            return mid;
        mid=(L+R)>>1;
    }
    return mid-1;
}
int main()
{
    //freopen("/home/test/in.txt","r",stdin);
    //freopen("/home/test/list.txt","w",stdout);
    for(long long  x=1;x<=52000;x++)//俩函数打表,用于binarysearch二分搜索
    {
        long long  n=getn(x);
        Fsave[x]=F(x,n);
    }
    for(long long  x=1;x<=52000;x++)
    {
        long long  n=getn(x);
        fsave[x]=g(n)+n*x;
    }
    long long t;scanf("%lld",&t);
    while(t--)
    {
        long long x;scanf("%lld",&x);
		    long long index_F=binsearch(x,Fsave);
		    x=x-Fsave[index_F];//x对应F序列中123...index_F的第几位
		    if(x==0)//如果恰好是结尾
		    {
		        printf("%lld\n",index_F%10);
		        continue;
		    }
		    long long index_f=binsearch(x,fsave);//x对应f中哪个数,f是123456789101112...
		    x=x-fsave[index_f];//x为该数字的第几位,比如122354第四位就是3
		    if(x==0)//刚好结尾
		    {
		        printf("%lld\n",index_f%10);
		        continue;
		    }
		    index_f++;
		    sprintf(aint,"%lld",index_f);
		    printf("%c\n",aint[x-1]);
        
    }
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值