poj1019 Number Sequence

在自己看来,思路虽然没错,但总是出现这样那样的细节问题。。。。

题目描述:http://poj.org/problem?id=1019

解题思路:开始是以为第i个数字,结果错了。原来是第i位。。。题目前80位

11212312341234512345612345671234567812345678912345678910123456789101112345678910

寻找第i位的数字分为四个步骤

1,找大块:大块是112......123456789,112123...100;也就是判断第i位所在序列的最大的数字多少位数字

2,找小块:找到第i位所在的序列,1234..i..,比如第8位在11234这个序列中,第11位在12345这个序列中

3,找数字:找到第i位所在的数字

4,找位:在数字中找到位

代码AC memory:416k  time:0ms

代码未优化 第一次写blog。。。

#include <stdio.h>
#include
<stdlib.h>
#include
<math.h>
//本程序中k是题目中的i
unsigned int cs,sz;
int a[]={0,1,11,192,2893,2889+9000*4+5};
unsigned
int erfen(int wei,unsigned int z)//用二分查找法找到i所在的小块序列
{
unsigned
int num=(int)pow(10,wei-1),low,high,mid,temp,temp1,temp2;
low
=num;
high
=num*10-1;
while(low<=high)
{
mid
=(low+high)/2;
temp1
=(mid-num+1-1)*a[wei]+(mid-num+1-1)*(mid-num+1-2)/2*wei;
temp
=(mid-num+1)*a[wei]+(mid-num+1)*(mid-num)/2*wei;
if(temp1<z&&z<=temp)//从找大块取得的位数最小数计算,到i的位数总数z大于前面的序列和,小于等于当前序列和
{
break;
}
else if(z>temp)
{
low
=mid+1;
}
else
{
high
=mid-1;
}
}
sz
=z-((mid-num)*a[wei]+(mid-num)*(mid-num-1)/2*wei);//取得i在序列中的位置
return mid;

}
int wei(int k)//找大块,就是看i所在序列最大数是几位数,返回位数
{
if(k>189414495)
{
cs
=189414495;
return 5;
}
else if(k>1395495)
{
cs
=1395495;
return 4;

}
else if(k>9045)
{
cs
=9045;
return 3;

}
else if(k>45)
{
cs
=45;
return 2;

}
else
{
cs
=0;
return 1;

}
}
int main(int argc, char** argv) {

unsigned
int k,z;
int n,d,i,num,no,i1;
scanf(
"%d",&n);
while(n--)
{
scanf(
"%d",&k);

d
=wei(k);
z
=k-cs;
num
=erfen(d,z);
i
=d;
while(1)//查找i所在数字的位数
{
if(sz<=(a[i]-i))
i
--;
else
{
break;
}
}

sz
=sz-a[i]+i;
no
=(sz-1)/i;
sz
=sz-no*i;
no
=(int)pow(10,i-1)+no;//找数字
printf("%d\n",no/(int)pow(10,i-sz)%10);//取位



}
return (EXIT_SUCCESS);
}

 



posted @ 2011-08-10 15:40  枫月寒  阅读(350)  评论(0编辑  收藏  举报