# Game of Two Stacks

- VK
vkreddy21 + 8 comments My c++ solution

#include <bits/stdc++.h> using namespace std; int main(){ int g; cin >> g; for(int a0 = 0; a0 < g; a0++){ int n; int m; int x; cin >> n >> m >> x; vector<int> a(n); for(int a_i = 0; a_i <n; a_i++){ cin >> a[a_i]; } vector<int> b(m); for(int b_i =0; b_i <m; b_i++){ cin >> b[b_i]; } int sum=0,count=0,temp=0,i=0,j=0; while(i<n && sum+a[i]<=x){ //considering only first stack and calculating count sum+=a[i]; i++; } count=i; while(j<m && i>=0){ //now adding one element of second stack at a time and subtracting the top element of first stack and calculating the count sum+=b[j]; j++; while(sum>x && i>0){ i--; sum-=a[i]; } if(sum<=x && i+j>count) count=i+j; } cout<<count<<endl; } return 0; }

- K
baghad_billa + 1 comment Good solution. Can you explain how did you come up with this solution? Thanks.

- VK
vkreddy21 + 3 comments first I'm only considering one stack and calculating the sum and count number.Then I'm adding one element from second stack at a time to the calculated sum and comparing it with required sum.If the calculated sum is greater we subract the last added element of first stack from sum.

farhan_tanvir_u1 + 1 comment what's the reason for i>=0 checking in the outer while loop ? I think the code should work without this.

- S
sagarkamdar37 + 1 comment It just restricts extra passes, since when i<0 you know that in the sum there are only numbers of second stack, you have already subtracted all the numbers of first stack. And now no need to continue.

- AS
singhjadaunatul + 0 comments [deleted]

aarce + 0 comments One of the games in test case 01 got me, your approach was very clever, help me rethink my approach, thank you.

- SZ
slz250 + 0 comments i was still confused after reading this but my realization below helped clarify; so for those who still may be confused:

the whole idea of adding the recently popped 2nd stack element to the sum and removing the last 1st stack element if the sum is greater than the sum limit is to maintain the max count thus far.

therefore, the max count will never decrease and will only increase if either 1) we can add an element from the 2nd stack without removing from the sum or 2) removing an "added element from 1st stack" allows for 2 or more additional elements from 2nd stack.

- GA
Gaurav6601 + 0 comments awesome logic

- SP
hotshot47 + 3 comments I understand your logic, but this is not a stack operation. The only thing you can do is push and pop. You are accessing the 1st stack elements by index in the array.

Correct thing to do is push all the poped elements from first stack into a 3rd stack and pop back again while you traverse through second one.

- EM
emarsc + 0 comments Using an index on an array in this manner is essentially the same thing as a stack. Its more efficient.

- FM
ferran_maylinch + 0 comments I agree with emarsc's comment.

From this problem/solution you may learn that data structures can be used in different ways, or even modify them to better fit the problem. Consider for example solving the classic stack with max where all the operations are O(1), i.e. without looping.

seregaxvm + 0 comments Formally you're right, but you can easily replace indexing with buffer stack. Logic itself will not change.

Arun_Gandhi + 1 comment but where is the use of stack or atleast its concept

- FM
ferran_maylinch + 0 comments See emarsc's comment.

- NA
NishthaAhuja + 2 comments good logic my brute force solution recursive is showing timeout for almost half of cases

- TB
timbliz + 0 comments [deleted] - TB
timbliz + 1 comment Same here! Since you always have two choices for your next pick, I figured a binary search tree was the obvious answer, but no! If you take the top two from each stack, our way calculates all six paths to get that same one answer! What an exponential waste! And I thought I was so clever while coding it!

- HH
hector_h_prez + 0 comments hahaha, happened the same to me. I even tried improving this by considering the zero scenarios, that is if there are zeros I would navigate recursively only until the next non-zero element, also, I tried improving it by checking if it's convenient navigating further, given the current global Max.

- R
rohanku_537 + 0 comments are u not facing timeout problem in some of the test cases?

sgrebenkin + 0 comments Implemented the same way on java. P.S.: With Scanner(System.in) the last test fails by TimeOut - use Fast I/O to resolve this.

- VV
vipulvikram3499 + 0 comments Nice approach. if we try greedy then there is problem in case where both corrosponding stack have same elements. Actually if we have problem in traversing both the stack simultaneously the best approach is to first traverse the 1st stack then start traversing second stack and manupulate the last added element from 1st stack as required in question.

bawejakunal + 3 comments A greedy strategy to pick the smaller element from the top elements of A and B is giving me wrong answer for many test cases. Any hints for that ?

- PB
pallav_borisagar + 3 comments Consider two stacks s1 = [17,1,1,1,8] and s2 = [8,8,4,5,9] and max sum = 20. Using greedy approach you will select from s2 because 8 < 17. You will end up removing 3 ints from s2. Contrary to that if you pick from s1, you end up picking 4 ints.

krishna858606 + 0 comments any logic to overcome this?

waqas_bukhari + 0 comments Then this is a dynamic programming problem. When you say stack, you are restricting the access only to the top element.

anuragh27crony + 0 comments Thanks for the example. It solved my doubts about proposed solution.

Freak_1231 + 0 comments [deleted]- IK
julkas + 1 comment I agree with you. A and B are stacks not arrays and we canâ€™t pop and push back. Decision is based only on 4 numbers - running sum, limit and top elements of A and B. Take minimum.

- QL
qingl97 + 0 comments My Java solution :

static int twoStacks(int x, int[] a, int[] b) { int ai = 0; int bi = 0; int count = 0; int sum = 0; // move bi to the position where if only take elements from B, last element it can take while (bi < b.length && sum + b[bi] <= x) { sum += b[bi]; bi++; } bi--; // loop exits only when bi reaches end or sum > x; in both case bi should decrease count = bi + 1; while (ai < a.length && bi < b.length) { sum += a[ai]; if (sum > x) { while (bi >= 0) { sum -= b[bi]; bi--; if (sum <= x) break; } // if even no elements taken from B, but still sum greater than x, then a[ai] should not be chosen // and loop terminates if (sum > x && bi < 0) { ai--; break; } } count = Math.max(ai + bi + 2, count); ai++; } return count; }

The key point is that the order how each element is selected does not matter, which makes things complicated at the first galance. But if we consider through the final result, we should know that the problem is equals to that, to choose the maximum number of elements from each stack so that them sum is no greater than x. The finally selected elements come from either both stacks, either all from one stack. So let's start with assuption that all from stack B. Then everthing time try adding one element from A, if the total sum is greater than x, then we should reduce elements we took from B until the sum is no more than x which will form a valid way of selection. Keep trying until no more elements can be taken from A or B. We just need to keep track of the maximum number of total elements selected.

- MK
mkamilov + 1 comment anyone tried dp to solve this?

thismoment + 0 comments I have. Timed out with the half of test cases.

akash_goel + 4 comments Had to use fast reader class to get AC in Java from here: http://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/.

Anybody got AC in Java using Scanner itself?

- BE
bassam_1981 + 0 comments he's right. I did mine in Java and I failed in one test case (timeout). I succeeded with the FastReader. This challenge is the worst I have had. I like the problem but this is the first time I had to use something other than scanner to pass the tests.

- KN
ketav + 0 comments I wish I had read this comment before. My java code worked with Scanner class but it quite ugly. (Test case 9 was most troublesome for me)

`public static int getMaxRemovedItems7(int [] a, int [] b, int x) { int total = 0; int max = 0; ArrayList<Integer> aPrefix = new ArrayList<>(a.length); ArrayList<Integer> bPrefix = new ArrayList<>(b.length); for(int i=0; i<a.length && total <= x; i++) { total += a[i]; aPrefix.add(total); } aPrefix.trimToSize(); total = 0; for(int i=0; i<b.length && total <= x; i++) { total += b[i]; bPrefix.add(total); } bPrefix.trimToSize(); int i=0; while((i+1)<aPrefix.size() && aPrefix.get(i+1) == 0) i++; int jStart = 0; while((jStart+1)<bPrefix.size() && bPrefix.get(jStart+1) == 0) jStart++; for(; i<aPrefix.size() && aPrefix.get(i)<=x; i++) { int j = nearest(bPrefix, jStart, bPrefix.size()-1, x-aPrefix.get(i)); if((aPrefix.get(i)+bPrefix.get(j)) > x && (i+j+1) > max) { max = i+j+1; } else if ((aPrefix.get(i)+bPrefix.get(j)) <= x && (i+j+2) > max) { max = i+j+2; } } if(max >= aPrefix.size() + bPrefix.size()) { return max; } i=0; if((i+1)<bPrefix.size() && bPrefix.get(i+1) == 0) i++; jStart = 0; while((jStart+1)<aPrefix.size() && aPrefix.get(jStart+1) == 0) jStart++; for(; i<bPrefix.size() && bPrefix.get(i)<=x; i++) { int j = nearest(aPrefix, jStart, aPrefix.size()-1, x-bPrefix.get(i)); if((bPrefix.get(i)+aPrefix.get(j)) > x && (i+j+1) > max) { max = i+j+1; } else if ((bPrefix.get(i)+aPrefix.get(j)) <= x && (i+j+2) > max) { max = i+j+2; } } return max; } private static int nearest(List<Integer> arr, int start, int end, int total) { if(start<end) { if(start == (end-1)) { return Math.abs(arr.get(start)-total) <= Math.abs(arr.get(end)-total) ? start : end ; } else { int mid = start + (end-start)/2; if(arr.get(mid) == total) { while(mid+1 < arr.size() && arr.get(mid) == arr.get(mid+1)) mid++; return mid; } else if (arr.get(mid) > total) { while(mid-1 >= 0 && arr.get(mid) == arr.get(mid-1)) mid--; return nearest(arr, start, mid, total); } else { while(mid+1 < arr.size() && arr.get(mid) == arr.get(mid+1)) mid++; return nearest(arr, mid, end, total); } } } return start; }`

bennattj + 0 comments Got AC with Scanner. Shouldn't be too difficult as the optimal algorithm is O(n + m):

int count = 0; final Stack<Long> leftStack = new Stack<>(); for (int i = 0; i < sums1.length && sums1[i] <= x; ++i) { ++count; leftStack.push(sums1[i]); } int max = count; for (int j = 0; j < sums2.length && sums2[j] <= x; ++j) { // check whether or not you can add the next sum from // right stack (sums2) to the current top of left stack if (!leftStack.isEmpty() && sums2[j] + leftStack.peek() > x) { // count was increasing but now we have to pop off // stack before adding next element in sums2, // check count now (because it's about to // decrease from removing from the left stack) if (count > max) max = count; // keep popping off the stack until the left sum // and the right sum are <= x OR we've emptied // the left stack while (!leftStack.isEmpty() && sums2[j] + leftStack.peek() > x){ --count; leftStack.pop(); } } // we just added from the right stack, so increment ++count; } if (count > max) max = count;

- M
mhmdk + 0 comments Thanks for the tip. I got AC using scanner , but barely AC

- EJ
kewltek + 1 comment Since this was supposed to be a stack problem I was also annoyed by other solutions using arrays. So here is my Python solution using the python stack operations pop, append and the equiv of peek is lst[-1]. Notice I also reversed the original data since Python pop is O(n) if you pop or delete the first element.

#!/bin/python3 import sys g = int(input().strip()) for a0 in range(g): n,m,x = input().strip().split(' ') n,m,x = [int(n),int(m),int(x)] a = list(map(int, reversed(input().strip().split(' ')))) b = list(map(int, reversed(input().strip().split(' ')))) total = 0 atmp = [] for i in range(n): val = a.pop() if total + val > x: break total += val atmp.append(val) max_count = len(atmp) cur_count = max_count while m: if total + b[-1] <= x: total += b.pop() m -= 1 cur_count += 1 if cur_count > max_count: max_count = cur_count continue if not len(atmp): break aval = atmp.pop() total -= aval cur_count -= 1 print (max_count)

pareksha + 0 comments Wow, thankyou so much

- GP
praveen31 + 0 comments Hi guys

for this input

13 10 92

14 10 11 8 14 14 15 7 16 6 8 7 4

19 14 6 2 19 17 9 5 11 19

the output should have been 7 right(14+10+11+8+14+14+15=86),but hacker rank ouput is showing 8,i dont know how.anything im doing wrong?

- HP
computerprogram3 + 0 comments # include

# include

using namespace std; int main() { int g; cin>>g; while(g--) { int n,m,x,y; long int s=0; cin>>n>>m>>x; int c[n],d[m]; for(int i=0;i>c[i];

`} for(int i=0;i<m;i++) { cin>>d[i]; } int i=0,j=0,k=0; while(s<=x&&(i<=n-1||j<=m-1)) { if(i<=n-1&&j<=m-1) {if(c[i]<d[j]) {s+=c[i];i++; } else { s+=d[j]; j++; } } else {if(i>=n) { s+=d[j++]; } else if(j>=m) { s+=c[i++]; } } k++; } cout<<k-1<<endl; s=0; }`

} can any tell mistake in this program?

- A
ramsay23 + 0 comments I tried DP but I'm getting "Abort Called" in last few test cases.

int twoStacks(int x, vector<int> a, vector<int> b) { int n=(int)a.size(); int m=(int)b.size(); int res=0; vector<vector<int>> D; D.resize(n+1); for (int i = 0; i < n+1; ++i) D[i].resize(m+1); D[0][0] = 0; for(int i=1; i<n+1; i++){ D[i][0] = D[i-1][0] + a[i-1]; if(D[i][0] <= x){ res = std::max(i+0,res); } } for(int j=1; j<m+1; j++){ D[0][j] = D[0][j-1] + b[j-1]; if(D[0][j] <= x){ res = std::max(0+j,res); } } for(int i=1; i<n+1; i++){ for(int j=1; j<m+1; j++){ D[i][j] = D[0][j] + D[i][0]; if(D[i][j] <= x){ res = std::max(i+j,res); } } } return res; }

deepak_097 + 0 comments I solved this question using Binary_search . Please let me know if you are facing any problem in understanding :)

#include<bits/stdc++.h> using namespace std; #define ll long long int int main() { ll t;cin>>t; ll i,j,k; ll n,m,x; while(t--) { cin>>n>>m>>x; ll a[n+5],b[m+5]; for(i=0;i<n;i++) cin>>a[i]; for(i=0;i<m;i++) cin>>b[i]; ll pa[n+5],pb[m+5]; pa[0]=a[0],pb[0]=b[0]; for(i=1;i<n;i++) { pa[i]=pa[i-1]+a[i]; } for(i=1;i<m;i++) { pb[i]=pb[i-1]+b[i]; } ll na=0,nb=0; for(i=0;i<n;i++) { if(pa[i]>x) break; else na++; } for(i=0;i<m;i++) { if(pb[i]>x) break; else nb++; } ll sa=0,sb=0,nod=0,max=0; ll ia=-1,ib=-1; for(i=0;i<n;i++) { ia=i; sa=pa[i]; sb=x-sa; if(sb<=0) break; ib=lower_bound(pb,pb+m,sb)-pb; if(pb[ib]!=sb) ib=ib-1; else { ll count=ib; for(j=count+1;j<m;j++) { if(sb==pb[j]) ib++; else break; } } nod=(ia+1)+(ib+1); if(nod>max) max=nod; } ll arr[4]; arr[0]=na;arr[1]=nb;arr[2]=max; sort(arr,arr+3); cout<<arr[2]<<"\n"; } return 0; }

Sort 128 Discussions, By:

Please Login in order to post a comment