#include<stdio.h>
int main()
{
int n=1,num;
float x=0,m;
printf("Enter no. of digits:\n");
scanf("%d",&num);
for(n=1;n<=num;n++)
{
m=(float)(2*n-1)/2*n;
if(n%2==0)
{
m=m*(-1);
}
x+=m;
}
printf("Summation is:\n%.4f\n\n",x);
}
I wanted to print the series 1/2 -3/4 5/6 -7/8......num where num is accepted by user. Its going pretty well when num is 1. But doesn't work correctly for any other value of num. Please help!
Related
`#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll solve(ll a, ll b, ll i){
//base case
if (a == 0) return i;
if (b > a) return i+1;
//recursive case
if (b == 1) {
return solve(a,b+1,i+1);
}
ll n = solve(a, b+1, i+1);
ll m = solve(a/b, b, i+1);
return min(n,m);
}
int main(){
int t;
cin >> t;
while(t--){
ll a, b;
cin >> a >> b;
cout << solve(a, b, 0)<< endl;
}
}`
Basically question is from codeforces (1485A). The problem is that when I give some big input like 50000000 a and 5 for b, this gives me segmentation fault error while the code works fine for smaller inputs. Please help me solve it.
Using recursion is a terrible choice. And you need to make all obvious algorithmic optimizations.
The key insight is that for any path that divides before increasing b, there is a path that is as good or better that does not divide before increasing b. Why divide by a smaller number when you can divide by a bigger one if you're going to use the steps to increase the number anyway?
With that insight, and removing recursion, the problem is trivial to solve:
#include <iostream>
unsigned long long divisions(unsigned long long a, unsigned long long b)
{
// figure out how many divide operations we need
int ops = 0;
while (a > 0)
{
a/=b;
ops++;
}
return ops;
}
unsigned long long ops(unsigned long long a, unsigned long long b)
{
// figure out how many divides we need with the smallest possible b
unsigned long long min_ops = (b == 1) ? (1 + divisions(a, b+1)) : divisions(a, b);
// try every sensible larger b to see if it takes fewer operations
for (unsigned long long num_inc = 1; num_inc <= min_ops; ++num_inc)
{
unsigned long long ops = num_inc + divisions (a, b + num_inc);
if (ops < min_ops)
min_ops = ops;
}
return min_ops;
}
int main(void)
{
int t;
std::cin >> t;
while (t--)
{
unsigned long long a, b;
std::cin >> a >> b;
std::cout << ops(a, b) << std::endl;
}
}
Again, the lesson is that you must make algorithmic optimizations before you start coding. No amount of great coding will make a terrible algorithm work well.
By the way, there was a huge hint on the problem page. Something in the problem tags gives the key optimization away.
My solution is timing out. Can someone point out the reason? The url to the problem is https://www.codechef.com/problems/COINS
#include<iostream>
using namespace std;
static long long int s=0;
int coin(long long int n)
{
if(n<=11)
{
s=s+n;
return n;
}
coin(n/2)
coin(n/3)
coin(n/4);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
long long int x,y;
while(cin>>x)
{
coin(x);
printf("%lld\n",s);
s=0;
}
}
With the approach taken in the solution above you'll keep recalculating the same numbers over and over again. The map that you mentioned in the comments is a technique called memoization, in this technique you're caching your results and so for each number, before calling recursively with coin(x) you first check if it's already in your memoization table and if it is you can return the result right away without recalculating it over and over again.
Good luck!
I am a college student so I'm still learning a lot. I ran into something interesting while making a project. I have this segment of code that works when it isn't placed in a for loop, but doesn't work when it is. I just want to understand why. Here is my code:
void setup() {
Serial.begin(9600);
int a[8];
for(int i=0;i<8;i++) {
a[i]=pow(2,i);
}
for(int i=0;i<8;i++) {
Serial.print(a[i]);
}
}
void loop() {
}
Here is the same code written without the first for loop (where the data gets written into the array):
void setup() {
Serial.begin(9600);
int a[8];
a[0]=pow(2,0);
a[1]=pow(2,1);
a[2]=pow(2,2);
a[3]=pow(2,3);
a[4]=pow(2,4);
a[5]=pow(2,5);
a[6]=pow(2,6);
a[7]=pow(2,7);
for(int i=0;i<8;i++) {
Serial.print(a[i]);
}
}
void loop() {
}
The first code outputs:
1
2
3
7
15
31
63
127
While the second code outputs:
1
2
4
8
16
32
64
128
Does anybody know? I really want to know why.
You are experiencing floating point round off. 2^4 will actually give you a value closer to 15.9999 and when this is assigned to an int, it truncates the decimal to 15. I would suggest doing bit shift operations when using powers of 2, such that:
for(int i=0;i<8;i++)
{
a[i]=(1 << i);
}
If you want to read up on bit shifting, look here.
If you want to know more about the floating point round off, look here.
Additionally if you wanted just a quick fix to your code closer to what you have, I believe this will also work:
for(int i=0;i<8;i++)
{
a[i]= (int) round( pow(2, i) );
}
This will round the floating result properly before casting it to an int.
Why does this program not work?
This is an exercise from http://www.freecodecamp.com/challenges/bonfire-factorialize-a-number
function factorialize(num)
{
for (i=num; i>0; i--)
{
num*= num[i];
}
return num;
}
factorialize(5);
Just a bit too late...
You just should use num *= i; instead of num *= num[i]. What your code did is trying to access the property i of the number object num, which is undefined.
Also you should change your loop initialization to for(var i = num - 1; i > 1; i--) to just create a local variable and not a global one. Also, multiplying num by num (first loop cycle) would give incorrect results. And last but not least, multiplying by 1 (last loop cycle) is useless.
You multiply with num[i] but num isn't an array (that is where you get the error). Also, your first iteration would multiply 5*5 which is wrong, it should be 5*4, so we start at i=num-1. and also, i>1 is enough, the num *= 1is pretty pointless.
this works:
function factorialize(num)
{
for (i=num-1; i>1; i--)
{
num*= i;
}
return num;
}
factorialize(5);
#Feinmann can achieve this answer using below recursive function.
function factorialize(num) {
if(num==0) {
return 1;
}
return num * factorialize(num-1);
}
Arduino not is able to multiply numbers from 40 onwards by 1000 for example
void setup() {
Serial.begin(9600);
}
void loop() {
float a = 60 * 1000;
Serial.print(a);
}
the result is -5536 .-. ??? what ??
I need to convert seconds to milliseconds, but I do not know alternatives to multiplication by 1000
The problem is that you are
taking a (signed) int and setting it to 60
taking a (signed) int and setting it to 1000
multiplying them, obtaining a signed int. This generates an overflow, so the result is -5536
converting this number in a float; -5536 -> -5536.0
The solution? Since you want to deal with floats... Operate with floats!
float a = ((float)60) * 1000;
float a = 60.0 * 1000;
The two solutions are the same; the first converts (int)60 in a float, then multiplies it by (int)1000, which gives you (float)60000.
The second tells the compiler that 60.0 is a float.
In both cases a float multiplied by an int gives you a float, so... No overflow!
The problem is that Serial.print converts a to signed integer. Try this:
Serial.print((float)a);
or this:
#include "floatToString.h"
char buffer[25];
Serial.print(floatToString(buffer, a, 5));