Sunday, December 18, 2011

UVA 10427 Naughty Sleepy Boys Solution

Problem Statement

Hasan and Tanveer are two naughty boys of the class. They spent most of their class time playing `Tic Tac Toe' whenever they get a chance to sit in back bench. But their teacher doesn't think that playing cross and naught is a way of making a class enjoyable. So, whenever she sees them playing she brings them to the front seat and makes them hear what she says. And you know listening to the teacher is not as enjoyable as playing `Tic Tac Toe'. So, within a couple of minutes, their eyes become dizzy and they fall into sleep resting their heads on the table. The teacher notices that and exclaims, ``You two naughty boys! Come over here.'' and she gives them some problem to solve which is lengthy and cumbersome. They try all the time not to get caught by the teacher while playing, or, for the least, not to get sleepy. But, pity for them, they hardly escapes the eagle eye of the teacher. Now, they are again caught red handed, brought to front bench, and as you know the usual case, they become sleepy. (poor Hasan and Tanveer! Couldn't the teacher be a little bit sympathetic to them?) This time the teacher is very angry and gives them a problem which is really too much for them. She asks them if she writes down the numbers from 1 to 1000 one after another what will be the 1000-th digit. You see what a tough problem for two little boys. Alam and Dalim start thinking that if they write down all the numbers like 1234567891011121314 ... ... it will take many hours for them. Moreover, the answer will possibly be incorrect because they can easily lose track of the numbers written. So, they are trying to find out a way to fool the teacher with the right answer. Can you find a way out for them?

Input
The input will contain one or more line each containing a positive integer N (N<100000000). Total line of the input file will not exceed 11000.

Output
For every N, you should calculate the N-th digit of the number 123456789101112 ... ... and print it on a line itself.

Sample Input

3
9
10
11
10000
50000

Sample Output

3
9
1
0
7
1
Solution 
This problem can be solved using brute-force. But it will required more time.
Here is the C implementation of this problem.
 
#include <cstdio>
#include <iostream>
#include <cstdlib>

//Time 0.008 s

using namespace std;
#define ITYPE unsigned int
#define DIG( a ) ( ( ( a ) >= '0' ) && ( ( a ) <= '9' ) )
ITYPE GETNUM ( void )//used to take faster I
{
 char 
  i ;

 ITYPE
  j ;

 i = getchar () ;
 while ( ! DIG( i ) ){
  if( i == EOF)
   return 0;
  i = getchar () ;
 }

 j = ( i - '0' ) ;

 i = getchar () ;
 while ( DIG( i ) )
 {
  j = ( ( j << 1 ) + ( j << 3 ) + ( i - '0' ) ) ;
  i = getchar () ;
 }
 return ( j ) ;
}

int main(){
 ITYPE i,j,k,l,cnt,pro,tmp,rem,n,ans;
 char number[20];

 //freopen("i.txt","r",stdin);

 while( n = GETNUM()){
  pro = 9;
  cnt = 1;
  ans = 1;
  while( true ){
   tmp = cnt * pro;
   if( tmp > n)
    break;
   n -= tmp;
   pro = (pro << 3) + (pro << 1);
   ans = (ans << 3) + (ans << 1);
   cnt++;
  }
  tmp = ans + n/cnt - 1;
  rem = n%cnt;
  if(rem){
   tmp++;
   sprintf(number,"%lu",tmp);
   printf("%c\n",number[rem-1]);
  }
  else{
   printf("%lu\n",tmp % 10);
  }  
 }


 return 0;
}

2 comments:

Kazi Mahbubur Rahman said...

Hi, Would you please briefly explain your procedure ? I already solved this problem in a different way. But your code looks pretty good than my code. my email address mahbub.kuet@gmail.com

Unknown said...

Idea was simple.
1 digit numbers(1-9) will take (9-1+1)*1 = 9 digits
2 digit numbers(10-99) will take (99-10+1)*2 = 180 digits
3 digit number(100-999) will take (999-100+1)*3 = 2700 digits

I had used this idea and to make faster run i had used faster Input subroutine and done some bit tweak.

Post a Comment