How to generate the nth number that consists only of even digits? - c++

I'm novice to Programming. I can find numbers consisting of even digits but my algorithm complexity is O(n). For large n my algorithm is too slow. So I need a more efficient algorithm. Can anyone help me?
For example, the first numbers with even digits are 0 , 2 , 4 , 6 , 8 , 20 , 22 , 24 , 26 , 28 , 40 etc. 2686 is another example of a number with even digits.
Here is my code: http://ideone.com/nsBzej
#include<bits/stdc++.h>
using namespace std;
long long int a[10],b[20];
long long int powr(int i)
{
long long int ans=5;
for(int j=2;j<=i;j++)
{
ans=ans*5;
}
return ans;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
long long int n,s,sum,p;
int t;
cin>>t;
for(int j=1;j<=t;j++)
{
s=20,sum=0;
a[1]=0, a[2]=2, a[3]=4, a[4]=6, a[5]=8;
for(int i=1;i<=17;i++)
{
b[i]=s;
s=s*10;
}
cin>>n;
for(int i=17;i>=1;i--)
{
p=powr(i);
while(p<n)
{
sum=sum+b[i];
n=n-p;
}
}
printf("Case %d: %lld\n",j,sum);
}
}
It is complexity O(n). But I get wrong verdict.

#include <stdio.h>
int main(void){
unsigned long long nth = 1000000000000ULL-1;//-1: 1 origin
unsigned long long k[30] = {0, 5};//28:Log10(ULL_MAX)/Log10(5) + 1
unsigned long long sum = k[1];
unsigned long long temp = 4;//4 : 2,4,6,8
int i;
//make table
for(i = 1; i < 30 ; ++i){
if(k[i] == 0){
temp *= 5;//5 : 0,2,4,6,8 , 2digits: 4*5, 3digits: 4*5*5
sum += temp;
k[i] = sum;
}
if(k[i] > nth)
break;
}
while(--i){//The same basically barakmanos
int n = nth / k[i];
printf("%d", n * 2);
nth -= n * k[i];
}
printf("%d\n", nth * 2);
return 0;
}

Related

This code gives unwanted '0' in output (C++)

I was making a program which coverts a list of prime numbers into yes-no format. By yes-no I mean that 2, 3, 5, 7, 11 gets converted into 1101010001 where '0' represents composite number and '1' represents prime number. This means that 2 is prime, 3 is prime, 4 is composite, 5 is prime, 6 is composite and so on. This is my code:
#include<iostream>
#include<fstream>
#include<cmath>
#include<string>
using namespace std;
unsigned long long int sti (string inp) //This function just converts string to integer
{
unsigned long long int size = inp.size();
unsigned long long int ret = 0 ;
for (unsigned long long int i = 0; i < size; i++)
{
ret += pow(10, i) * stoi(to_string(inp[size-i-1]));
}
return ret;
}
int main()
{
ifstream ifs("1.txt");
string temp = "";
string ret = "";
unsigned long long int inp1 = 0;
unsigned long long int inp2 = 0;
ifs >> temp;
inp1 = sti(temp);
ret+='1';
int diff=0;
while(true)
{
inp2= inp1;
ifs >> temp;
inp1 = sti(temp);
if(inp1==inp2)
{
break;
}
diff = inp1-inp2-1;
for(int i=0; i<diff; i++)
{
ret+='0';
}
ret+='1';
}
cout<< ret;
}
But when I try to convert first 10 primes, ie - 2,3,5,7,11,13,17,19,23,29, The code outputs 1101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010001010001000001
The code gives unexpected zeroes between 7 and 11.
Can anyone please help me with what is happening?

Last digit of partial sum of Fibonacci series

I'm trying to find the last digit of the sum of the fibonacci series from a starting to an end point. As we find the last digit using %10 , Fibonnaci will repeat it's last digit sequence every 60 times - using the Pisano Series
My attempt at the solution:
We find the last digits of the first 60 digits, store them in an array and then continuously loop over and sum over the digits starting from n%60 to m. We then finally modulo 10 the result.
#include <iostream>
#include <vector>
using std::vector;
int fibonacci_fast(long long n,long long m) {
// write your code here
long long a[60];
a[0]=0;
a[1]=1;
long long sum=0;
for(long long i=2;i<60;i++)
{
a[i] = a[i-1]+a[i-2];
a[i] = a[i] % 10;
}
int j=0;
int p=1;
int c=0;
for(int i=n%60;;i++)
{
if(i==60)
{
i=i%60;
}
sum=sum+a[i];
c=c+1;
if(c==m)
{
break;
}
}
return sum%10;
}
int main() {
long long from, to;
std::cin >> from >> to;
std::cout << fibonacci_fast(from, to) << '\n';
}
The major issue I'm having with this current code is that for lower values, it works fine, but if I input higher values such as 0 to 239, It only works when the condition changes to if(c+1)==m which then results in the smaller values solutions turning wrong.
The c counter works correctly though and goes up to 239 but I still cannot figure out the issue with the code.
#include <vector>
using std::vector;
int fibonacci_fast(long long n,long long m) {
// write your code here
long long a[60];
a[0]=0;
a[1]=1;
long long sum=0;
sum = a[0] + a[1];
for(long long i=2;i<60;i++)
{
a[i] = a[i-1]+a[i-2];
a[i] = a[i] % 10;
sum = (sum + a[i]) % 10;
}
int x = (m - n + 1)/60;
sum = (sum * x) % 10;
int i = n + 60 * x;
while(i <= m)
{
sum = (sum + a[i%60]) % 10;
i++;
}
return sum;
}
int main() {
long long from, to;
std::cin >> from >> to;
std::cout << fibonacci_fast(from, to) << '\n';
}
I think you need to set the variable c to be equal to the value of n and not 0 (zero)
int c = n;
Also, please clear the concept whether you want to include the index m or not.
Example, if user enters:
n -> 10
m -> 20
Then your code provided above will add the last digit values of the Fibonacci numbers from the index 10 to the index 19 only. So please clear this doubt of mine, then I will add further.

Can time complexity of this code be further reduced?

I am getting a timeout for several test cases of a programming challenge. Any help will be appreciated.
That's the exercise:
A palindromic number reads the same both ways. The smallest 6 digit palindrome made from the product of two 3-digit numbers is 101101 = 143 * 707.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N (any input greater than 101101 and less than 1000000).
What I have is this:
#include<bits/stdc++.h>
using namespace std;
bool check_palindrome(unsigned int a)
{
unsigned int temp = a;
unsigned int digit ; //used for reversing
unsigned int rev_a = 0; //final reversed number
int power = 5; //used for reversing
unsigned int modulo; //used for reversing
while(temp > 0)
{
digit = temp / int(pow(10,power));
temp = temp % int(pow(10 , power));
rev_a = rev_a + digit * (pow(10 , 5 - power));
power--;
}
return (a == rev_a) ? true : false ;
}
int main()
{
int T;
unsigned int n;
scanf("%d" , &T);
for(int i = 0 ; i < T ; i++) //for entering number of test cases
{
unsigned int max_palindrome=0;
scanf("%d" , &n); //Input the number
for(int p = 101 ; p <= 999 ; p++)
{
int m ;
int other_number = int(n/p);
if(other_number > 999 )
m = 999;
else
m = other_number;
for( int q = m ; q >100 ; q--)
{
if( p*q < 101101)
break;
bool palindrome = check_palindrome(p*q);
if(palindrome)
{
if(p*q > max_palindrome)
max_palindrome = p*q;
break;
}
}
}
printf("%d\n" , max_palindrome);
}
return 0;
}
Rather than trying all reasonable pairs of factors you could start from the given number and count down. Each time you come to a palindromic number, see if it can be expressed as a suitable product (checking all possible factors from sqrt(palindrome) down to 101).
The advantage is that as soon as you find a suitable palindrome you're done, you don't have to keep searching.
EDIT: You don't even have to search for palindromes, you can just enumerate them by working through all possible front halves and computing the corresponding back halves.
As #AlanStokes said, you're checking more values than you need. In addition, here's a more reasonable palindrome check.
bool is_palindrome(unsigned n) {
unsigned rn = 0;
for (unsigned x = n; x; x /= 10)
rn = 10 * rn + x % 10;
return rn == n;
}

Project Euler 14: the output is always zero

I am trying to solve Project Euler 14 and the output is always zero.
The basic Idea is n/2 when n is even and 3n + 1 when n is odd.
Then if m/2 < n or m < n (where m/2 or m is previous number whose number had already been calculated) give the number of iterations as iterations stored.
I am storing the iterations of previous numbers.
#include<iostream>
using namespace std;
bool ok=true;
unsigned long int p[1000001]; //initialization of array p to store iterations
unsigned long int q[2]={1,1}; // initialization of two element array to store the max sequence number
unsigned long int x=0;
int Colltz(unsigned long int num,unsigned long int count) { // function starts
unsigned long int j=num;
p[0]=0; //Initial iterations for 1 and 2
p[1]=1; // Initial value for 1
p[2]=2; // Initial val for 3
while(ok) { // while loop
if((j%2==0)&&(j/2>num)) { //(to check whether j is available in the array if not it divides it further until j/2<num
j=j/2;
++count;
}
if((j%2==0)&&((j/2)<num)) { // since j/2 the arry should contin the number and the collatz vlue is +1
++count;
p[num]=p[j/2]+count;
ok=false;
break;
}
if ((j%2)!=0) { //if it is odd
j=3*j+1;
++count;
Colltz(j,count);
}
if(j<num) { // if j < num then j is Collatz of j is calculated and added
p[num]=p[j]+count;
ok=false;
break;
}
if((p[num]>=q[1])) {
q[0]=num; // to get the max count
q[1]=p[num];
}
}// end of while loop
return q[1];
}
int main() {
unsigned long int i=3;
unsigned long int j=0;
int counted=1;
while(i<6) {
j=Colltz(i,counted);
++i;
}
cout<<j;
}
So basically my function should take in the number (for which I have initialized count to 0) and then find out whether it is even or odd and if it is even whether it is greater than n or less and then follow steps accordingly and if it is odd whether it is less than n and calculate accordingly.
Your code seems a little bit messed up! Check my solution and see whether that helps :
#include <stdio.h>
unsigned long int Collatz(unsigned long int);
int main()
{
unsigned long int n,i,bingo;
int ChainLen=0;
for(i=1;i<=1000000;i++)
{
if((n=Collatz(i)) > ChainLen)
{
ChainLen=n;
bingo=i;
}
}
printf("\n%lu\n",bingo);
return 0;
}
unsigned long int Collatz(unsigned long int x)
{
if(x==1)
return 1;
if(x%2==0)
{
return 1 + Collatz(x/2);
}
else
return 1 + Collatz(x * 3 + 1);
}

Dynamic Programing : Rod cutting implementation error

Given a rod of length n inches and a table of prices pi for
i = 1, 2,... n, determine the maximum revenue rn obtainable by cutting up
the rod and selling the pieces.
Bottom_Up_Cut_Rod(p, n)
1 let r[0...n] be a new array
2 r[0] = 0
3 for j = 1 to n
4 q = -infinity
5 for i = 1 to j
6 q = max(q; p[i] + r[j - i])
7 r[j] = q
8 return r[n]
Implementation
#include <iostream>
#include <algorithm>
using namespace std;
int RodCut(long long P[],long long n)
{
long long r[n];
r[0]=0;
for(long long j=0;j<n;j++)
{
long long q = -100000;
for(long long i=0;i<j;i++)
{
q = max(q , P[i] + r[j-i]);
}
r[j] = q;
}
return r[n];
}
int main()
{
long long num;
long long N;
long long K;
cin>>N;
long long a[N];
for (long long i = 0; i < N; i++)
{
cin>>num;
a[i] = num;
}
int res = 0;
res = RodCut(a,N);
cout<<"Answer : "<<res;
return 0;
}
My input is 1 5 8 9 10 17 17 20 24 30, but output is 2686348.
What is wrong with my code?
There are several issues. You want the main loop to go from j = 1 to n, because it represents the best you can do using j elements.
You should stick to using either ints or long longs.
int r[n+1];
r[0]=0;
// Calculate best we can do with j elements
for(int j=1;j<=n;j++) {
int q = -100000;
for(int i=0;i<j;i++) {
q = max(q , P[i] + r[j-i-1]);
}
r[j] = q;
}
return r[n];
This seems to give me the right solution for a variety of inputs.
There are two things. One is returning r[n], which should be r[n-1]. Second, start j from 1 to n, since r[0] is getting replaced with -100000 in the first round.
Also, r[0] should be P[0]; i.e. you'll atleast make P[0] money given a rod with length 1.
Also, note that q should be P[j], thats the minimum you'll make.
So assuming the array is P[0..n] // not including n
and r[0..n] is your memo for applying DP
foreach index from (0..n] // not including n
r[index] = P[index]
foreach splitIndex from (0..index] // not including index
r[index] = max(r[index], P[splitIndex] + r[index-splitIndex-1]
return r[n-1]