POJ1019 NumberSequence 【數學公式轉化題】

絕風發表於2014-06-21

這題也是一看感覺自己能做,就拿出筆和紙開始寫寫畫畫了,寫的也蠻爽(下午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;
}


相關文章