I am trying to find out the number of perfect squares in the given range. The method I am following is provided on: digital_root
The code I have implemented is not giving correct answers sometimes because This method does not consider the numbers like 10,1000 etc.
Please help me to work out this method.
int cot=0;
void squares(int a,int b){
if(a==b){
int digit,digit_root=0,no;
no=a;
digit=no%10;
if(digit==2||digit==3||digit==7||digit==8){
}else{
no=a;
while(no>0){
digit=no%10;
if((digit==0)||(digit==9)){
}else{
digit_root=digit_root+digit;
digit_root=digit_root%9;
}
no=no/10;
}
if(digit_root==0||digit_root==7||digit_root==1||digit_root==4){
if(digit_root==1){
if(a)
}
cot++;
}
}
}else{
int c=(a+b)/2;
squares(a,c);
squares(c+1,b);
}
}
int main() {
int a,b,t;
cin>>t;
for(int i=0;i<t;i++){
cin >> a>>b;
squares(a,b);
cout << cot<<endl;
cot=0;
}
return 0;
}
the best algorithm will probably be to subtract sqrt(bigger number) - sqrt(other num), i.e. something like this
int a = 1,b=100;
if (sqrt(a) != int(sqrt(a)){
cout<<int(sqrt(b))-int(sqrt(a))<<endl;}
else{
cout<<int(sqrt(b))-int(sqrt(a))+1<<endl;}
the logic is very simple, perfect square is natural num * the same natural num so, 1*1,2*2,3*3,4*4 and so on
So you just need to get the closest perfect sqrt of the bigger num and subtract it with the smaller num (just be careful in case that the smallest num is a perfect square itself)
There's too much going on here. Simplify it. Write a function that determines whether a single number is a perfect square. Get that working right. Then use that function to determine how many perfect squares there are in your range. That probably shouldn't be recursive; that's just too hard to follow. Use a loop that covers the range:
for (int i = a; i <= b; ++i)
if (is_perfect_square(i))
++count;
It's easy to print numbers from 1 to N, and the numbers will be perfect square.
Here is the logic to check perfect square
/*function definition to check perfect square*/
int isPerfectSquare(int number)
{
int iVar;
float fVar;
fVar=sqrt((double)number);
iVar=fVar;
if(iVar==fVar)
return 1;
else
return 0;
}
You dont need all these costly calculations.
Things are really simple here.
Instead of looping from A to B and checking for perfect squares,
we can calculate the first integer square root of A at O(1) and
count the rest perfect squares with simple increments of power n,
up to B. In this way we can avoid costly calculations.
But even better, we can even avoid loops by just using ceil and floor.
For example, square numbers between 1000 and 2000:
sqrt(1000) = 31.6 --> ceil(31.6) --> 32
sqrt(2000) = 44.7 --> floor(44.7)--> 44
therefore the difference of these two plus one gives us the number of perfect squares.
#include <cmath>
#include <iostream>
using namespace std;
int main() {
int A, B;
//get the range [A,B]
cin >> A >> B;
cout << floor(sqrt(B)) - ceil(sqrt(A)) + 1 << end;
return 0;
}
Related
I was writing an algorithm for a problem that goes as follows:
Consider an algorithm that takes as input a positive integer n. If n is even, the algorithm divides it by two, and if n is odd, the algorithm multiplies it by three and adds one. The algorithm repeats this until n is one. For example, the sequence for n=3 is as follows:
3→10→5→16→8→4→2→1
Original question can be found here
The algorithm that I wrote for it is as follows:
#include <iostream>
#include<vector>
using namespace std;
void check(long int n, vector<int> &arr);
int main(){
long int n;
cin>>n;
vector<int> arr; //Vector to store values of n
check(n,arr);
for(unsigned int i=0;i<arr.size();i++){
cout<<arr[i]<<' '; //Printing the final values of n
}
return 0;
}
void check(long int n,vector<int> &arr){
arr.push_back(n);
if(n%2==0){ //if n is even
n=n/2;
if(n!=1){
check(n,arr);
}
else if(n==1){
arr.push_back(1);
}
}
else{ //if n is odd
n=(n*3)+1;
if(n!=1){
check(n,arr);
}
else if(n==1){
arr.push_back(1);
}
}
return;
}
My solution is working perfectly for smaller values of n. However when n becomes large enough- especially somewhere around 138367(this was the first test case when the answer got wrong according to the compiler), the values of n printed at the end also start to include some 'negative numbers', which is somewhat unreasonable.
For instance, if I input n=986089625, in the beginning, the next number that follows it in the end result is -1336698420. While the correct number should be 2958268876. Surprisingly the next number that follows is correct, but at certain (random) intervals, the numbers are becoming negative.
I know the algorithm can be simplified further, but I'm not able to understand the problem with this one. I assume there's something subtle that I'm missing!
You can see how this works with this simple example
#include <limits.h>
#include <iostream>
int main()
{
int n = INT_MAX;
std::cout << "n=" << n << '\n';
std::cout << "n+1=" << n + 1 << '\n';
unsigned m = UINT_MAX;
std::cout << "m=" << m << '\n';
std::cout << "m+1=" << m + 1 << '\n';
}
giving
n=2147483647
n+1=-2147483648
m=4294967295
m+1=0
When the limit is reached, a wrap around occurs to either INT_MIN or zero, depending on the signedness of the integer type.
The same happens also in the opposite direction of course, wrapping from INT_MIN to INT_MAX or from zero to UINT_MAX.
Typical int (signed 32-bit long) can store numbers only upto 2,147,483,647 (2**31 - 1) and the number 2958268876 exceeds this limit.
You are using long int for calculation, so you should use it also for the elements of vector.
In other words, the three vector<int>s should be replaced with vector<long int>.
First of all, I would clarify that I am new to programming and started with c++ recently. There was a problem related to Legendre's formula in my math textbook and I thought about making a program related to it. It takes a number from user n, and finds the highest power of n which divides n!
It runs fine for a lot of numbers but messes up for a few others and it is completely random. This is a snippet from the code.
#include <iostream>
#include <math.h>
using namespace std;
int prime(int);
int calc(int, int);
int main()
{
int n;
int hpf=2;
cout<<"This program finds highest power x that divides x!"<<endl;
cout << "Enter number : " << endl;
cin>>n;
for(int i=2; i<=n; i++)
{
bool p=prime(i);
if(p==true && n%i==0)
hpf=i;
}
cout<<"The highest prime factor of the number is : "<<hpf<<endl;
int p=calc(hpf, n);
cout<<"The highest power of "<<n<<" that divides "<<n<<"!"<<" is : "<<p;
return 0;
}
calc(int f, int n)
{
int c=0 , d=1, power=1, i=0;
while(i>=0)
{
int x= pow(f,power+i);
if(i>0 && n%x==0)
d++;
if(x<=n)
{
c+=n/x;
i++;
}
else
break;
}
return c/d;
}
prime(int n)
{
bool isPrime = true;
for(int i = 2; i <= n/2; i++)
{
if (n%i == 0)
{
isPrime = false;
break;
}
}
return isPrime;
}
I pass the highest prime factor of n and the number n itself to int calc(int, int).
Now here is the problem:
when I input n=9, I get
Enter number :
9
The highest prime factor of the number is : 3
The highest power of 9 that divides 9! is : 2
on the other hand, if I input 25, I get
Enter number :
25
The highest prime factor of the number is : 5
The highest power of 25 that divides 25! is : 6
This is clearly wrong, the highest power should be 3.
It also works for bigger numbers accurately, but not all.
PS: I use codeblocks.
I'm not sure why exactly it works for 9 and not for 25(your program seems fine, but you probably have a problem when you calculate d or something), although both are squares of primes and your code seems to take care of that, but I do know why it doesn't work with number like 12. This happens because your code only looks at the highest prime factor and ignores the others. This will give you the true result when the other prime factors appear less frequently then the biggest one, but in all other cases this assumption leads to wrong results, because the highest is then also limited by smaller primes. So a correct solution has to take care of all prime factors.
For that you first need to factor the number(getting the prime factors and their power!). You can just google that if you are unsure how to do that. I don't want to include it here because then the answer would get to long.
Then you need to find how often the number is present in the factorial.
As you already know(at least you used it in your code) you can count by summing up the occurence as a factor of each power of the prime in every factor of the factorial which can be done through division like this:
n/p¹ + n/p² + n/p³ + n/p⁴ + …
That can be put into a simple function(using a simple self-made power calculation):
int occurenceInFaculty(int factor, int faculty) {
int sum = 0;
for(int power = factor; power <= faculty; power *= factor) { // Go through all powers
sum += faculty/power;
}
return sum;
}
Now you can calculate the occurrence for each of the prime factors of your number and if you divide by the power of that prime factor in the factorization you get an upper limit for the highest power.
Then all that's left to do is take the minimum over all prime factors and you are done.
Assuming one possible way of storing the prime factorization here is what the resulting code could look like:
Somewhere in the beginning of your code:
typedef struct {
int prime;
int power;
} PrimeFactor;
Assuming a prime factorization method like this:
PrimeFactor* factorization(int number, int* factors) {
// Factorize here. Return a pointer to an array of PrimeFactors and set the pointer factors to the arrays length.
}
And then the calculation part:
int number = 25; // Put your number here.
int length = 0;
PrimeFactor* factors = factorization(25, &length);
int min = number; // Some reasonable upper border because n! < n^n
for(int i = 0; i < length; i++) {
if(occurenceInFaculty(factors[i].prime, number)/factors[i].power < min)
min = occurenceInFaculty(factors[i].prime, number)/factors[i].power;
}
This program also gets 25 right!
I'm creating a program that returns the least quantity of sums required to get to a number (n) using only 1, 2, 6 and 13. It works perfectly for small values of n, but once n gets to values like 200 it takes the program too much time to calculate the result.
Therefore, I have two questions:
1. Is there any way to make the recursion faster?
2. Should I avoid using recursion and use a loop instead?
Here's the commented code:
#include <iostream>
#define MAX 500000
using namespace std;
void cal(int inp, int &mini, int counter = 0);
int main (void)
{
//Gets input
int n;
cin >> n;
//Defines mini as the MAX result we can get
int mini = MAX;
//Calls the function
cal(n, mini);
//Prints the best result
cout << mini << endl;
return 0;
}
void cal(int inp, int &mini, int counter)
{
//Breaks recursion if it finds an answer
if(!inp)
{
if(counter<mini) mini = counter;
return;
}
//Breaks recursion if the input is negative
//or the counter is more than the best result
else if((inp<0) || (counter>mini)) return;
//Counts amount of recursions
counter++;
//Tries every combination
cal(inp-13, mini, counter);
cal(inp-6, mini, counter);
cal(inp-2, mini, counter);
cal(inp-1, mini, counter);
return;
}
Thank you
The problem is your brute force. Let me suggest something better:
Preliminaries: If you have two 1s, it is always better to use a 2. If you have three 2s, it is better to use a 6. If you have thirteen 6s, it is better to use six thirteens.
So the any admissable sum will always look like n = 13m+k where k is written as a sum of 1, 2, and 6. With the preliminaries, we know that for the optimal sum k will never exceed 1+2*2+12*6 = 77. (The reverse doesn't hold. Not any number below 78 is best written without 13s of course.) So brute forcing those is good enough. You can then use a lookup table.
This could still be optimized further, but it should not break down at 200.
Assuming you have found your first 77 entries (which can be optimized as well) you can do this (still unoptimized ;-):
int num_13 = ((n-78) / 13) + 1;
int sum_length = MAX;
for (i = num_13; i*13 < n; i++) {
int tmp = entries_77[n-i*13]+i;
if (tmp < sum_length) {
num_13 = i;
sum_length = tmp;
}
}
I would be even quicker to compile an array for the equivalence classes modulo 13, since for any given equivalence class any number exceeding 78 will have the same k.
You can use DP (Dynamic Programming) approach to solve your problem. It's well known Coins Problem
Your recursion needs a memoization to avoid repetitive calculation. And no need for the second and third parameter of the recursion. I have updated and put explanation on your code. Let me know if you have any confusion.
#include <iostream>
#include <string.h>
#define INF 999999
using namespace std;
int cal(int inp);
int mem[502];
int main (void)
{
//Gets input
int n;
cin >> n;
//initialzing the array for using with memoization
memset(mem,-1,sizeof(mem));
//Calls the function
//Prints the best result
cout << cal(n) << endl;
return 0;
}
//returns the minimum quantity of sum operations to get inp.
int cal(int inp)
{
//Breaks recursion if it finds an answer.
//Return cost 0. As in this stage no processing was done.
if(!inp)
return 0;
// Returning infinite cost for invalid case.
if(inp < 0)
return INF;
int _ret = mem[inp];
// If already visited here before then no need to calcuate again.
// Just return previous calculation. This is called memoisation.
// If not visited then _ret would have equal to -1.
if(_ret >=0 )
return _ret;
_ret = INF;
//Tries every combination and takes the minimum cost.
_ret = min(_ret, cal(inp-13)+1);
_ret = min(_ret,cal(inp-6)+1);
_ret = min(_ret,cal(inp-2)+1);
_ret = min(_ret,cal(inp-1)+1);
// Updating the value so that can be used for memoization.
mem[inp] = _ret;
return _ret;
}
This will also work for larger numbers. Complexity is 4*n.
I recently stumbled on this Project Euler Problem #25:
The 12th term, F12, is the first term to contain three digits.
What is the first term in the Fibonacci sequence to contain 1000 digits?
I just know C++98 and no other programming language. I have tried to solve it, making changes to get support of c++11.
Working:
#include <iostream>
#include<cstdio>
long len(long); //finding length
int main()
{
/* Ques: What is the first term in fibonacci series to contain 1000 digits? */
int ctr=2;
unsigned long first, second, third, n;
first=1;
second=1;
std::cout<<"\t **Project EULER Question 25**\n\n";
for(int i=2;;++i)
{
third=first+second;
// cout<<" "<<third;
int x=len(third);
// cout<<" Length: "<<x;
// cout<<"\n";
first=second;
second=third;
ctr++;
if(x>1000) // for small values, program works properly
{
std::cout<< " THE ANSWER: "<< ctr;
system("pause");
break;
}
}
}
long len(long num)
{
int ctr=1;
while(num!=0)
{
num=num/10;
if(num!=0)
{
ctr++;
}
}
return(ctr);
}
I know this is brute force, but can i make it more efficient so that i get the answer ?
Any help will be greatly appreciated.
EDIT:
By using Binet's Formula, as suggested by PaulMcKenzie and implementing it as:
#define phi (1+sqrt(5))/2
int main(void)
{
float n= ((999 + (1/2)*log10(5))/(log10(phi))); //Line 1
cout<<"Number is : "<<n;
return 0;
}
Output: 4780.187012
Changing Line 1, above, to :
float n= ((999 + log10(sqrt(5)))/(log10(phi)));
OUTPUT: 4781.859375
What could be possibly the error here?
unsigned long simply can't hold 1000-digit number. So you will get the overflow in your code when first and second will reach the unsigned long limit. If you want a brute force solution - consider use of something like biginteger library or write one by yourself.
here x,y<=10^12 and y-x<=10^6
i have looped from left to right and checked each number for a prime..this method is very slow when x and y are somewhat like 10^11 and 10^12..any faster approach?
i hv stored all primes till 10^6..can i use them to find primes between huge values like 10^10-10^12?
for(i=x;i<=y;i++)
{
num=i;
if(check(num))
{
res++;
}
}
my check function
int check(long long int num)
{
long long int i;
if(num<=1)
return 0;
if(num==2)
return 1;
if(num%2==0)
return 0;
long long int sRoot = sqrt(num*1.0);
for(i=3; i<=sRoot; i+=2)
{
if(num%i==0)
return 0;
}
return 1;
}
Use a segmented sieve of Eratosthenes.
That is, use a bit set to store the numbers between x and y, represented by x as an offset and a bit set for [0,y-x). Then sieve (eliminate multiples) for all the primes less or equal to the square root of y. Those numbers that remain in the set are prime.
With y at most 1012 you have to sieve with primes up to at most 106, which will take less than a second in a proper implementation.
This resource goes through a number of prime search algorithms in increasing complexity/efficiency. Here's the description of the best, that is PG7.8 (you'll have to translate back to C++, it shouldn't be too hard)
This algorithm efficiently selects potential primes by eliminating multiples of previously identified primes from consideration and
minimizes the number of tests which must be performed to verify the
primacy of each potential prime. While the efficiency of selecting
potential primes allows the program to sift through a greater range of
numbers per second the longer the program is run, the number of tests
which need to be performed on each potential prime does continue to
rise, (but rises at a slower rate compared to other algorithms).
Together, these processes bring greater efficiency to generating prime
numbers, making the generation of even 10 digit verified primes
possible within a reasonable amount of time on a PC.
Further skip sets can be developed to eliminate the selection of potential primes which can be factored by each prime that has already
been identified. Although this process is more complex, it can be
generalized and made somewhat elegant. At the same time, we can
continue to eliminate from the set of test primes each of the primes
which the skip sets eliminate multiples of, minimizing the number of
tests which must be performed on each potential prime.
You can use the Sieve of Eratosthenes algorithm. This page has some links to implementations in various languages: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes.
Here is my implementation of Sieve of Erathostenes:
#include <string>
#include <iostream>
using namespace std;
const int k = 110000; //you can change this constant to whatever maximum int you would need to calculate
long int p[k]; //here we would store Sieve of Erathostenes from 2 to k
long int j;
void init_prime() //in here we set our array
{
for (int i = 2; i <= k; i++)
{
if (p[i] == 0)
{
j = i;
while (j <= k)
{
p[j] = i;
j = j + i;
}
}
}
/*for (int i = 2; i <= k; i++)
cout << p[i] << endl;*/ //if you uncomment this you can see the output of initialization...
}
string prime(int first, int last) //this is example of how you can use initialized array
{
string result = "";
for (int i = first; i <= last; i++)
{
if (p[i] == i)
result = result + to_str(i) + "";
}
return result;
}
int main() //I done this code some time ago for one contest, when first input was number of cases and then actual input came in so nocases means "number of cases"...
{
int nocases, first, last;
init_prime();
cin >> nocases;
for (int i = 1; i <= nocases; i++)
{
cin >> first >> last;
cout << prime(first, last);
}
return 0;
}
You can use the Sieve of Erathostenes to calculate factorial too. This is actually the fastest interpretation of the Sieve I could manage to create that day (it can calculate the Sieve of this range in less than a second)