This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So, there are ways to do this, and/or optimize this. Stupid that I am, I immediately wants to implement a recursive function, which later caused a segmentation fault, and then I tried to adopt dynamic programming, and it seemed to work, but somehow I got Wrong answer.
Problem Here
So here's my code, and I think it's pretty self-explanatory.
#include <iostream>
using namespace std;
int cycleLength(long long int);
int cycleLengthResult[1000000];
int main(int argc, char *argv[])
{
int i = 0, j = 0, cur = 0, max = 0;
while ( cin >> i >> j )
{
if ( i > j ) //swap to ensure i <= j
{
int s = i;
i = j;
j = s;
}
for ( int k = i ; k <= j ; ++ k )
{
cur = cycleLength(k);
if (cur > max) max = cur;
}
cout << i << " " << j << " " << max << endl;
max = 0;
}
}
int cycleLength(long long int arg)
{
if ( arg > 1000000 ) //if out of array bound, then don't memorize, just calculate
{
if (arg % 2 == 0)
{
return 1 + cycleLength(arg/2);
}
else
{
return 1 + cycleLength(arg*3+1);
}
}
if (!cycleLengthResult[arg-1]) //if result for arg doesn't exist then....
{
int valueForArg = 0;
if (arg == 1)
{
valueForArg = 1;
}
else if (arg % 2 == 0)
{
valueForArg = 1 + cycleLength(arg/2);
}
else
{
valueForArg = 1 + cycleLength(arg*3+1);
}
cycleLengthResult[arg-1] = valueForArg;
}
return cycleLengthResult[arg-1];
}
I passed all the sample inputs, and also (1, 1000000) for speed test. But it seemed that it's not the problem.
I want to fix my code, and not change the methodology used, of course, I can just not use recursive, and use a loop instead in main, which wouldn't overflow. But it's fun.
Read the statement carefully:
The integers i and j must appear in the output in the same order in which they appeared in the input
So save them after reading and print the saved values.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to come up with the following algorithm:
The input is unsigned integer number.
The output is the size of the array of unordered pairs of unsigned integers, which, when multiplied, give a number less then or equal to the input.
I have one naive implementation working, but it is way too slow for my purpose (compl. O(n^2), please correct me if I am wrong). My question is: how to make it faster?
#include <iostream>
using namespace std;
bool notInYet(int t[][1], int mi, int ma, int m) {
bool val = true;
for(int i = 0; i < m; i++)
if(t[i][0] == mi && t[i][1] == ma)
val = false;
return val;
}
int main() {
int n, m;
int t[100000][1];
cin >> n;
m = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j*i <= n && j <= i; j++) {
if(notInYet(t, j, i, m)) {
t[m][0] = j;
t[m][1] = i;
//cout << "t[" << m << "] = (" << t[m][0] << ", " << t[m][1] << ")" << endl;
m++;
}
}
}
cout << m << endl;
return 0;
}
I think it should be something like that - pseudocode:
int counter = 0;
for int i = 1 to sqrt(input), i++ {
if (input % i == 0) counter++;
}
counter is an answer if you need unique pairs, otherwise you need to multiply it by 2 (and sub 1 if input % sqrt(input) == 0)
If I'm reading correctly #jauser's algorithm doesn't get what you want.
If the target is 5, then the pairs are (1,1)(1,2)(1,3)(1,4)(1,5)(2,2). So the answer is 6. His algorithm will produce 1 because 5 mod 1 == 0, but not mod 2.
In general, if the target is n, then you know (1,k) is a counted pair for all k from 1 to n. There are n - 1 + 1 = n of these. Now you have (2,k) for k from 2 to floor(n/2) (skip 1 because your pairs are unordered). There are n/2-2+1 of these. Continue this through (j,k) for j= floor(sqrt(n)). Putting this is pseudocode
count = 0;
for j in 1 .. floor(sqrt(n))
count += floor(n / j) - j + 1;
Maybe there is even some clever series solution that gets this to a constant time calculation.
Am I missing something in the problem?
Well, you are spending a lot of time effectively calculating the following per i:
j= n/i;
So if you just do that you reduce the complexity to O(n). You can halve it also since the list will contain both (i, j) and (j, i) when i!=j, but that won't reduce the overall complexity.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to solve USACO trainings, The "Your Ride Is Here" problem can be solved with this algorithm:
#include <iostream>
#include <conio.h>
using namespace std;
int Calculated(char * calc_me);
int main() {
char * comet_name = (char*)calloc(sizeof(char), 7);
if (comet_name == NULL) {return 0;}
char * group_name = (char*)calloc(sizeof(char), 7);
if (group_name == NULL) {free(comet_name); return 0;}
cout << "Enter the name of the comet: ";
cin >> comet_name;
cout << "Enter the name of the group: ";
cin >> group_name;
if ((Calculated(comet_name) % 47) == (Calculated(group_name) % 47)) {
cout << "GO";
}
else {
cout << "STAY";
}
free (group_name);
free (comet_name);
return 0;
}
int Calculated (char * calc_me) {
int i;
int total = 1;
for (i = 0; i < 7; i++) {
if (calc_me[i] == '0') {break;}
total *= calc_me[i] - 64;
}
getch();
return total;
}
Im trying to change the for loop with do-while loop, Here is my code,so I replaced it with do-while, it doesn't work, can anyone mention me which part I am doing it wrong?
#include <iostream>
#include <conio.h>
using namespace std;
int Calculated(char * calc_me);
int main() {
char * comet_name = (char*)calloc(sizeof(char), 7);
if (comet_name == NULL) {return 0;}
char * group_name = (char*)calloc(sizeof(char), 7);
if (group_name == NULL) {free(comet_name); return 0;}
cout << "Enter the name of the comet: ";
cin >> comet_name;
cout << "Enter the name of the group: ";
cin >> group_name;
if ((Calculated(comet_name) % 47) == (Calculated(group_name) % 47)) {
cout << "GO";
}
else {
cout << "STAY";
}
free (group_name);
free (comet_name);
return 0;
}
int Calculated (char * calc_me) {
int i;
int total = 0;
do
{
total *= calc_me[i] - 64;
i += 1;
}while(i < 7);
getch();
return total;
}
this is the sample input :
COMETQ
HVNGAT
GO
ABSTAR
USACO
STAY
if (calc_me[i] == '0') {break;}
should read
if (calc_me[i] == '\0') {break;}
and that condition is missing from your do-while version, along with the initialisation of i.
But the main problem is that you changed the initial value of total from 1 to 0:
int total = 0;
so this line
total *= calc_me[i] - 64;
keeps multiplying zero by the next value.
AH!! found it!!
You have initialized total to 0. So, every multiplication becomes 0 hence your functions always returns 0.
Initialize your total variable to 1 and it should work.
In the code snippet below, you need to initialize i with a value before you can do i += 1. You do it in the for statement in the for-loop, similarly you need to do it for the do-while loop as well.
int i = 0; // initialize to 0
int total = 0;
do
{
total *= calc_me[i] - 64;
i += 1;
}while(i < 7);
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Thats all in title.
In simple i had write this.
#include <iostream>
using namespace std;
int main()
{
int a,i;
cout<<"Enter a number: ";
cin>>a;
for (i=2;i<=a/2;i++)
{
if (a%i==0)
{
cout<<"Its not Prime Number.";
system ("pause");
return 0;
}
}
cout<<"Its a Prime number.";
system ("pause");
}
The main thing is WITHOUT using loop and with recursive function.
You mainly want to look at making the body of your for loop into a function that takes "int i" as a parameter. Then you put a test for i<=a/2 at the beginning of the function and call "function(i + 1)" at the end of it.
Here's a recursive primality test function:
int test_prime(unsigned n, unsigned d)
{
if (n < 2) {
return 0;
}
if (d == 1) {
return 1;
} else {
if (n % d == 0) {
return 0;
} else {
return test_prime(n, d - 1);
}
}
}
Use it like:
unsigned n;
std::cin >> n;
std::cout << (test_prime(n, n / 2) ? "prime" : "not prime") << "\n";
Here is a solution based on recursion that can also perform the computation at compile-time if an compile-time constant value is provided:
constexpr bool check_divisibility(int i, int j)
{
return (j == 1) ? false :
((i % j == 0) ? true : check_divisibility(i, j - 1));
}
constexpr bool is_prime(int i) { return !check_divisibility(i, i / 2); }
Here is how you could use it in your client code:
#include <iostream>
using namespace std;
int main()
{
static_assert(is_prime(11), "Error!"); // Computed at compile-time
int x = 15;
cout << is_prime(x); // Computed at run-time
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Here is part of my code. The rest is just the function definitions. I have an array of 20 x 20 that records the temperature of a plate. I need to reiterate through a loop until no cell in the array changes more than 0.1 degree (I refresh the values through every iteration) How would you monitor the largest change for any cell in an array in order to determine when to stop iterating? Right now I have tried this, but it doesn't output correctly. I believe it is because I am incorrectly defining my previous one to compare the current one with.
while (true)
{
bool update = false;
for (int a = 1; a < array_size -1; a++)
{
for (int b = 1; b < array_size -1; b++)
{
hot_plate[a][b] = sum_cell(hot_plate, a, b);
}
}
for (int a = 1; a < array_size-1; a++)
{
for (int b = 1; b < array_size-1; b++)
{
hot_plate_next[a][b]=sum_cell(hot_plate_next, a,b);
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
hot_plate_next[a][b] = hot_plate[a][b];
cout << hot_plate[a][b] << " ";
}
}
if (!update) {
break;
}
}
The problem is that you overwrite update when a cell has a smaller change. In that case, any cell that has a smaller change will stop the iteration.
Structure your loop like this:
float largest_change = 0.0f;
do {
largest_change = 0.0f;
for (...) {
float new_value = ...
float change = abs(new_value - hot_plate[a][b]);
if (change > largest_change)
largest_change = change;
hot_plate[a][b] = change;
}
} while (largestChange > 0.1f);
When you put:
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) < 0.1)
{
update = false;
}
inside the 2nd nested for-loop, you are setting "update" to false if ANY of the cells have a difference less than 0.1 between current and previous checks, instead of ALL cells like you wanted.
Update your code as follows:
bool update = false;
and
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
(I would have put >=, but you said "until no cell in the array changes more than 0.1 degree")
Edit as per request: to output the matrix cleanly, add the following line:
cout << "\n";
here:
for (int a = 1; a < array_size-1; a++)
{
for (int b = 1; b < array_size-1; b++)
{
hot_plate_next[a][b]=sum_cell(hot_plate_next, a,b);
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
hot_plate_next[a][b] = hot_plate[a][b];
cout << hot_plate[a][b] << " ";
}
cout << "\n"; // Add this line
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
The following is my simple attempt at generating Armstrong numbers. But it only outputs "1". What might be wrong?
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
int main()
{
clrscr();
int r;
long int num = 0, i, sum = 0, temp;
cout << "Enter the maximum limit to generate Armstrong number ";
cin >> num;
cout << "Following armstrong numbers are found from 1 to " << num << "\t \n";
for(i=1;i<=num;i++)
{
temp = i;
while( temp != 0 )
{
r = temp%10;
sum = sum + r*r*r;
temp = temp / 10;
}
if ( i == sum ) {
cout << i;
sum = 0;
}
}
getch();
return 0;
}
You need to always set sum = 0 inside the for-i-loop.
Armstrong numbers: n-digit numbers equal to sum of n-th powers of their digits.
From your code
sum = sum + r*r*r;
'r*r*r' isn't n'th power of the number.
The first thing is that you're assuming that n (as in the nth power) is always three (in your r*r*r). That's only true if your initial value has three digits (as with the 153 example).
You need to count the digits in your initial number to calculate n, and then replace your r*r*r with raising r to the nth power.
This doesn't explain why 153 isn't found, though. The reason for that is because you aren't reseting sum to zero unless you find a match. You need to reset it to zero whether you found a match or not.
you can calculate n using log:
n = log(i)+1
then calculate r^n correctly and use it in your summation: sum += r^n;. r*r*r is not the correct way of calculating it.
Your code only works with n=3 : sum = sum + r*r*r;
You must use the pow() function (http://www.codecogs.com/reference/c/math.h/pow.php) to compute powers. (Or create a custom one.)
To summarize the right, but partial answers:
// #include <math.h>
for (long int i = 1; i <= num; i++)
{
long int n = 0, sum = 0; // <--- here
long ing temp = i;
while ( temp != 0 )
{
++n;
temp /= 10;
}
temp = i;
while ( temp != 0 )
{
int r = temp%10;
sum += int(pow(double(r), n)); // <-- here
temp /= 10;
}
if ( i == sum )
{
cout << i;
sum = 0;
}
}
#Power-inside, I saw your code, its difficult to change your code and edit it, but I have written a similar code to generate Armstrong numbers in a given limit, and it works fine.
Here it is....
#include<iostream.h>
#include<conio.h>
class arm
{
int a;
public:
void display();
};
void arm::display()
{
cout<<"Enter any number to find armstrong numbers less than it";
cin>>a;
for(int i=a;i>=1;i--)
{
int d=i;
int b=i;
int c=i;
int count=0;
while(b!=0)
{
b=b/10;
count++;
}
int l,m;
m=0;
for(int k=1;k<=count;k++)
{
l=c%10;
c=c/10;
m=m+l*l*l;
}
if(d==m)
cout<<d<<"\t";
}
}
void main()
{
arm k;
k.display();
getch();
}