GCJ Qualification Round 2017 Problem B. Tidy Numbers
Problem Statement: https://code.google.com/codejam/contest/3264486/dashboard#s=p1
Description: Basically you are given a number and one has to find the largest number whose digits are all in increasing order. For example given 132 , largest number less than this where all digits are in increasing order is 129 since 9 > 2 > 1
For input 200 , output should be 199
My Approach:
Since the input can be very large, I am keeping the number in string rather than integer.This also save all modulo and division operation.
Start scanning from right hand side .
Case 1:
If number at the index is 0, make it as 9 and also decrements number at previous index. Do this until it is non-zero.
Case 2:
If number at this index is smaller than its previous , for example 32 , since 2 is smaller than 3
we know the best we can do is,make this index 9.
Not only this index but all the indices on right side of this index should be 9 as well.
Next decrements the previous digit by 1.
That's all, this passes all small and large data-set.
Code:
#include <bits/stdc++.h>
#include <algorithm>
#include <tgmath.h>
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
#define pi 3.14159265358979323846264338327950288419716939937510582097494459230
using namespace std;
typedef unsigned long long ull;
typedef long double ld;
int main(int argc, char*argv[])
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >>T;
for (int k=0; k<T; k++)
{
string N;
cin >>N;
int count = N.size();
for (int i= count-1; i>0;i--)
{
while(1)
{
if(N[i] =='0')
{
int index =i,d;
do{
N[index] ='9';
for(int kk=index+1; kk<count;kk++)
N[kk] = '9';
char a = N[index-1];
d = atoi(&a);
index =index -1;
}while(d==0);
N[index] = 48 + (d-1);
break;
}
else if(N[i] < N[i-1])
{
N[i] = '9';
for(int kk=i+1; kk<count;kk++)
N[kk] = '9';
char a = N[i-1];
int d = a - 48;
N[i-1] = 48 + (d-1);
}
else
break;
}
}
if(N[0]=='0')
cout <<"Case #"<<k+1<<": "<<N.substr(1, count)<<endl;
else
cout <<"Case #"<<k+1<<": "<<N<<endl;
}
}
Description: Basically you are given a number and one has to find the largest number whose digits are all in increasing order. For example given 132 , largest number less than this where all digits are in increasing order is 129 since 9 > 2 > 1
For input 200 , output should be 199
My Approach:
Since the input can be very large, I am keeping the number in string rather than integer.This also save all modulo and division operation.
Start scanning from right hand side .
Case 1:
If number at the index is 0, make it as 9 and also decrements number at previous index. Do this until it is non-zero.
Case 2:
If number at this index is smaller than its previous , for example 32 , since 2 is smaller than 3
we know the best we can do is,make this index 9.
Not only this index but all the indices on right side of this index should be 9 as well.
Next decrements the previous digit by 1.
That's all, this passes all small and large data-set.
Code:
#include <bits/stdc++.h>
#include <algorithm>
#include <tgmath.h>
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
#define pi 3.14159265358979323846264338327950288419716939937510582097494459230
using namespace std;
typedef unsigned long long ull;
typedef long double ld;
int main(int argc, char*argv[])
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >>T;
for (int k=0; k<T; k++)
{
string N;
cin >>N;
int count = N.size();
for (int i= count-1; i>0;i--)
{
while(1)
{
if(N[i] =='0')
{
int index =i,d;
do{
N[index] ='9';
for(int kk=index+1; kk<count;kk++)
N[kk] = '9';
char a = N[index-1];
d = atoi(&a);
index =index -1;
}while(d==0);
N[index] = 48 + (d-1);
break;
}
else if(N[i] < N[i-1])
{
N[i] = '9';
for(int kk=i+1; kk<count;kk++)
N[kk] = '9';
char a = N[i-1];
int d = a - 48;
N[i-1] = 48 + (d-1);
}
else
break;
}
}
if(N[0]=='0')
cout <<"Case #"<<k+1<<": "<<N.substr(1, count)<<endl;
else
cout <<"Case #"<<k+1<<": "<<N<<endl;
}
}
Comments
Post a Comment