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 7 years ago.
Improve this question
I am getting Time Limit Exceeded on submitting this question
Question:
Let's consider a triangle of numbers in which a number appears in the first line, two numbers appear in the second line, three in the third line, etc. Develop a program which will compute the largest of the sums of numbers that appear on the paths starting from the top towards the base, so that:
on each path the next number is located on the row below, more precisely either
directly below or below and one place to the right;
the number of rows is strictly positive, but less than 100
all numbers are positive integers between O and 99.
My Code:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int trian(int i,int j);
long long int n,a[100][100];
int main()
{
long long int t,i,j,v,k;
scanf("%lld",&t);
for(i=0;i<t;i++)
{
scanf("%lld",&n);
for(j=0;j<n;j++)
{
for(k=0;k<j+1;k++)
{
scanf("%lld",&a[j][k]);
}
}
v=trian(0,0);
printf("%lld\n",v);
}
}
int trian(int i,int j)
{
if(i>=n)
return 0;
else
return (a[i][j]+(std::max(trian(i+1,j),trian(i+1,j+1))));
}
Why I am getting Time Limit Exceeded?
Consider this triangle (ignore the numbers):
1
2 3
There are 2 possible paths to take here. Let's add a row:
1
2 3
4 5 6
The 4 can only be reached via a path that ends directly above, the 5 has two paths which can reach it, the 6 can only be reached from the path previously ending left above of it. We now have 4 possible paths. Another row:
1
2 3
4 5 6
7 8 9 0
That's 8 possible paths. Do you see a pattern? Let's describe the path straight down to 7, starting from 1:
D = DOWN
R = DOWN AND RIGHT
DDD
The (single) path to 0:
RRR
Since in each step you go down one row, you can only chose between the two possibilities number of rows - 1 times, thus giving you:
2^(number of rows - 1) possible paths
With 100 rows, that's alot. Your code tries to compute each of these paths separately. Assuming computing 1 path takes 1 nanosecond (which would be blazing fast) computing them all would take more than 2 * 10^16 years. Well, ...
Time Limit Exceeded
So you now know that you cannot just compute every possible path and take the maximum. The main issue is the following:
1
2 3
4 5 6
One path to the 5 is 1 + 3 + 5, the path to the 6 is 1 + 3 + 6. Your code computes each path separately, thus 1 + 3 will be computed twice. If you save that result, you'll get rid of most of the unnecessary computations.
How could you store such results? Well, 1 + 3 is the computation of the path arriving at 3, so store it there. What if a number (say 5) can be reached by multiple paths?
5 could be reached via 1 + 2 + 5 or 1 + 3 + 5.
Any path going through the 5 will give a higher result if it wen't through the 3 first, so only remember this path (and ignore the path through the 2, it's useless now).
So, as an algorithm:
For each row, starting at row 1 (not the first, but the second): For each entry: Calculate the maximum of the entries left above (if available) and directly above (if available) and store the result + the entry's value as new value for the entry. Then, find the maximum of the last row.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 months ago.
Improve this question
I am a student and am looking for a way to solve a problem online with content like the image below
Please solve it for me with C++ code
If you want to solve such a problem, then you need split the big problem in to smaller problems. Then the solution is easier.
So, let's first strip of the '*'. They are always starting a row and ending it. This is not needed in the beginning.
Next. You see some sequences, like
1
121
12321
1234321
123454321
1234321
12321
121
1
You see that the digits will be incremented by one until we hit the maximum value for this row and then decremented again until they are 1.
The decreasing numbers are also not important at the moment, because, it is simple to decrement them from the maximum number.
Stripping of the decremented numbers, we will get:
1
12
123
1234
12345
1234
123
12
1
And this looks like a triangle and can be generated mathematically by a typical triangular function.
We want to calculate the maximum number in a row from the row value istelf. Applying the algorithm from the triangular function, will always result in a formular with the "abs"-function. So taking the absolute value.
We will then get something like the below:
Row 5-abs(Row-5)
0 0
1 1
2 2
3 3
4 4
5 5
6 4
7 3
8 2
9 1
10 0
We see also that the number of output lines is double the input value.
We can then do a simple increment/decrement loop, to show the digits according to the before shown values.
Then we add a little bit the output of the "". Please note, that the "closing" star "" at the end of the line is not needed in the first and last row.
Having explained all the above, we can now start writing the code. There are really many many potential solutions, and I just show you one of them as an example.
Please have a look and implement your own solution.
#include <iostream>
#include <cmath>
int main() {
// Tell user what to do
std::cout << "\nPlease add number for the triangle: ";
// Get the maximum extent from the user. Limit values
int maxN{};
if ((std::cin >> maxN) and (maxN >= 0) and (maxN < 10)) {
// Now we want to print row by row
for (int row=0; row <= (maxN * 2); ++row) {
// Calculate the maximum value that should be shown in this row
int maxValueForRow = maxN - std::abs(row-maxN);
// You may uncomment the following line for getting more info
//std::cout << maxValueForRow << '\t';
// Always print at least on beginning star
std::cout << '*';
// Now we want to print the digits. Start counting with 0
int i = 0;
// Print and increment digits
for (i = 0; i < maxValueForRow; ++i) std::cout << i+1;
// And now decrement the digits and print them
for (i=i-2; i >= 0; --i) std::cout << i+1;
// Show closing star only, if we are not in first or last row
if (maxValueForRow > 0) std::cout << '*';
// Start a new line
std::cout << '\n';
}
}
else std::cerr << "\n\nError: Invalid input\n";
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm new in C++ and I have been thinking about this.
There is a question that asks:
Find the sum of the multiples of 2 under 547.
How am I supposed to code the program to keep on multiplying the user input and adding them at the same time until they reach the number under 547, then stop the process and count the result?
Find the sum of the multiples of 2 under 547
Lets break this down...
A "Multiple of two" is a number that can be divided by two evenly. Meaning there is no remainder. Look at this link for more info.
Ok we know what a "Multiple of two" is now lets look at the sum...
We want to add up "Multiples of two" under 547. Meaning we will count up to 547 by two and add them together.
so 2 + 4 + 6 + .... + 544 + 546 = A big number
Like #Mureinik posted...we start by defining and initializing something to hold our sum (adding up all the counting by two) in.
long sum = 0;
Then we need to count up to 547 by twos.
for(int i = 0; i < 547; i += 2){
}
This is a for loop. It will execute what is inside the { } until the condition is false. It defines i as the integer of 0. The condition is i < 547. It will also increment i by two each time through the loop. That is what the i += 2 part does. (i += 2 is the same thing as i = i + 2)
So now we have something to hold our summation in (sum) and we have a means of counting by two (the for loop). All we have to do is add up the numbers.
sum += i;
This will take care of that for you. Like you hopefully have guessed sum += i is short hand for sum = sum + i;. i will always be a "Multiple of two" because we are always adding 2 to i. Once i gets to 548 it will fall out of the loop and stop adding up the sum.
Like others have commented it will not hurt to look up some tutorials on the web. I know that it can be over whelming you just have to stick with it.
Hope this clears up some stuff for you. Code On.
You just need to iterate over the multiples and sum them:
long sum = 0;
for (int i = 0; i < 547; i +=2) {
sum += i;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Can u Guys Please give me tips on how to reduce the compilation time of my c or c++ programmes...
Some basic simple techniques will be helpful.
I was solving a question through a site(https://www.codechef.com/problems/TRISQ)
The Question was :-
What is the maximum number of squares of size 2x2 that can be fit in a right angled isosceles triangle of base B.One side of the square must be parallel to the base of the isosceles triangle.Base is the shortest side of the triangle.
First line contains T, the number of test cases.
Each of the following T lines contains 1 integer B.
Output exactly T lines, each line containing the required answer.
Sample Input
11
1
2
3
4
5
6
7
8
9
10
11
Sample Output
0
0
0
1
1
3
3
6
6
10
10
MY CODE
#include<iostream>
using namespace std;
int main()
{
int T,N,a,i,j;
cin>>T;
while(T--)
{
a=0;
cin>>N;
N=N/2;
N--;
j=N;
for(i=0;i<j;i++)
{
a+=N;
N--;
}
cout<<a<<endl;
}
}
So how do u guys think that this code (for eg) can be edited for better compilation time?
First profile.
Second, turn up optimizations levels on you compiler.
Thirdly, replace your for loop with multiplication / algebra. For example, the line
a+=N
is the fundamental basis for multiplication (repetitive addition), and the loop can be replaced by:
a += j * N; N -= j;
Replacing the loop will speed up your program (if your compiler hasn't already replaced the loop).
Printing the assembly language for the function will show how the compiler applied optimizations.
Edit 1:
Less code means a faster build time as well. I don't know if time difference in building is measurable.
I have solved the 1st of three phases of a panhellenic competition (it is now over) but i am interested in knowing whether there is any simpler complexity algorithm or not
7 9
5 7
4 2
3 6
2 3
1 7
6 2
4 6
1 5
3 4
int main()
{
ifstream in("domes.in");
ofstream out("domes.out");
int orio,z;
in>>orio;
in>>z;
int domes[orio];
for(int i=0;i<orio;i++){domes[i]=0;}
int k;
for(int i=0;i<2*z;i++)
{
in>>k;
domes[k-1]++;
}
int c=0;
for(int i=0;i<orio;i++)
{
if(domes[i]<2)
c++;
}
out<<c;
return 0;
}
it is about some places(represented by numbers)the first two numbers are number of places (orio) and the number of matches (z). The places are "connected" somehow (meaningless). You should find how many places have less than 2 connections and the output (c in this case) is the number of the places that have less than 2 connections. k is a variable used temporarily to insert each number and plusplus the times it is "seen" . If it is seen it means that it is connected to another place. I don't think there is a simpler solution, but some of my peer's programs needed less time to run and that troubled me
Codeforces problem 158B-http://codeforces.com/problemset/problem/158/B
I am getting an unexpected output for test case 5.I think I should get 1 as output but I am it as 2.Please guide me.Judge's log:
Test: #5, time: 30 ms., memory: 380 KB, exit code: 0, checker exit code: 1, verdict: WRONG_ANSWER
Input
2
2 1
Output
2
Answer
1
Checker Log
wrong answer expected 1, found 2
My solution:
#include<iostream>
using namespace std;
int n,a[100000],i,b,c,d,e,f,g,h;
int main()
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
b=0;
c=0;
d=0;
e=0;
for(i=0;i<n;i++)
{
if(a[i]==1) //To check for number of 1,2,3 and 4 membered groups.
b=b+1;
if(a[i]==2)
c=c+1;
if(a[i]==3)
d=d+1;
if(a[i]==4)
e=e+1;
}
f=e;
if(d>b) //More 3 member groups than 1.
{
f=f+d; //f=f+b+(g-b) 3 and 1 member groups combine.Remaining 3 i.e. (g-b) member groups will can't combine with 2 member groups.Hence,they take separate taxies.
g=-1;
}
if(b>=d) //More 1 member groups than 3.
{
f=f+d;
g=b-d; //g=remaining 1 member groups.
}
h=(2*c)%4; //Empty seats in last taxi.Possible values can be 0,1,2,3.
if(h==0)
f=f+(c/2);
else
f=f+((c+1)/2);
if(g!=-1)
{
g=g-h; //Remaining 1 member groups after combining with remaining seats in last 2 member taxi.
if((g%4)==0)
f=f+(g/4);
else
f=f+(g/4)+1;
}
cout<<f;
}
If your input is 2 2 1, then b and c will both be 1, making f 0 and g 1 in the first set of conditionals. h will be (2 * 1) % 4 or 2, making an update to f (0 + 1 = 1). Since g is 1, g-h is -1, which will lead to you executing f=f+(g/4)+1 which is f=1 + (-1/4)+1 which is 1 + 0 + 1 = 2 in integer math.
I think you wanted to check if g-h>0 instead of g!=-1, but there are a ton of places you could simplify your code. Note that using a debugger and stepping through this would have shown you where your problems are much faster, and be much more helpful to increasing your skills, than asking SO.
Just for anyone else looking at this question, this is a fairly simple answer to the problem.
Do it by hand and see if you get the same answer. If you get the same answer by hand as the computation, your algorithm is wrong. If you don't, your code is wrong.
Print variables from intermediate computations to see if they are what you think they should be.
Make sure, if it might matter, that you reinitialize your variables (including arrays) before each use.
Other tips:
Use a switch statement instead of multiple if-equal statements.
Name your variables. It helps you keep track when looking at your code.
When you have multiple variables with similar use, consider using an array instead. b, c, d, and e all seem similar.