uva 12486-Space Elevator

//http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3930

//Problem description:

Space Elevator

China is building a space elevator, which will allow the launching probes and satellites to a much
lower cost, enabling not only scientific research projects but also space tourism.
However, the Chinese are very superstitious, and therefore have a very especial care with the
numbering of floors in the elevator: they do not use any number containing the digit “4” or the
sequence of digits “13”. Thus, they do not use the fourth floor or the floor 13 or the floor 134 nor the
floor 113, but use the floor 103. Thus, the first floors are numbered 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 15,
16, . . .
As the space elevator has many levels, and levels must be numbered, the Chinese asked you to
write a program that, given the level, indicates which number should be assigned to it.


Input

The input contains several test cases. Each test case consists of a single line containing an integer
N which indicates the floor whose number should be determined.


Output

For each test case, print a line containing a single integer indicating the number assigned to the
N-th floor.
Restrictions

• 1 ≤ N ≤ 10^18


Examples
Sample input
1
4
11
12
440
Sample output
1
5
12
15

666

//解题思路:一个数位dp的题,dp[i][0]记录不含4和13且第一位数字不为3的个数,dp[i][1]记录不含4和13但第一位数字为3的个数,dp[i][2]记录里面含有4或13,或都有的个数,最后状态转移如下所示:


dp[i][0]=7*(dp[i-1][0]+dp[i-1][1])+dp[i-1][0];
dp[i][1]=dp[i-1][0]+dp[i-1][1];
dp[i][2]=dp[i-1][1]*2+dp[i-1][0]+10*dp[i-1][2];
这题还有一个注意的地方就是long long 的范围不够用了,要用unsigned long long; 


//Code as follows:

#include<stdio.h>
#include<string.h>
unsigned long long dp[22][3],num[22];
void init()
{
	int i;
	memset(dp,0,sizeof(dp));
	dp[0][0]=1;
	for(i=1;i<20;i++)
	{
		dp[i][0]=7*(dp[i-1][0]+dp[i-1][1])+dp[i-1][0];
		dp[i][1]=dp[i-1][0]+dp[i-1][1];
		dp[i][2]=dp[i-1][1]*2+dp[i-1][0]+10*dp[i-1][2];
	}
	num[0]=1;
	for(i=1;i<20;i++)
		num[i]=num[i-1]*10;
}

unsigned long long get(unsigned long long n)
{
	int i,flag=0;
	unsigned long long p[22],pnum[22],sum=0;
	memset(pnum,0,sizeof(pnum));
	i=0;
	while(n)
	{
		p[++i]=n%10;
		pnum[i]=pnum[i-1]+num[i-1]*p[i];
		n/=10;
	}
	for(;i;i--)
	{
		sum+=dp[i-1][2]*p[i];
		if(p[i]==1)
			flag=1;
		else if(p[i]>1)
		{
			if(i>1)
				sum+=dp[i-1][1];
			if(p[i]==3)
			{
				if(flag)
				{
					sum+=pnum[i-1]+1;
					break;
				}
			}
			else if(p[i]>3)
			{
				if(flag)sum+=dp[i][1];
				if(p[i]==4)
				{
					sum+=pnum[i-1]+1;
					break;
				}
				else 
				{
					sum+=dp[i-1][1];
					sum+=dp[i-1][0];
				}
			}
			flag=0;
		}
		else flag=0;		
	}
	return sum;
}
unsigned long long find(unsigned long long n)
{
	unsigned long long tem,mid,start=0,end=num[19]+1,t;
	while(start<=end)
	{
		t=start%2+end%2;
		mid=start/2+end/2+t/2;
		tem=mid-get(mid);
		if(end==mid)break;
		if(tem>=n)
			end=mid;
		else start=mid+1;
	}
	return end;
} 
int main()
{
	unsigned long long n;
	//freopen("out.out","w",stdout);
	init();
	while(scanf("%llu",&n)!=EOF)
		printf("%llu\n",find(n));
	return 0;
}




你可能感兴趣的:(c,Integer,input,each,output)