0% found this document useful (0 votes)
13 views

AP Lab Assignment Fast Learner Nemesis

The document outlines a programming lab course focused on complex problems in computer science, including algorithms for trapping rainwater, optimizing power station distribution, and manipulating subsequences of strings. It contains code examples in C++ for various problems, such as calculating trapped water, maximizing city power, and processing queries on arrays. Additionally, it discusses fixed-bound subarrays and provides implementations for these problems.

Uploaded by

tusharsingh06.ts
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

AP Lab Assignment Fast Learner Nemesis

The document outlines a programming lab course focused on complex problems in computer science, including algorithms for trapping rainwater, optimizing power station distribution, and manipulating subsequences of strings. It contains code examples in C++ for various problems, such as calculating trapped water, maximizing city power, and processing queries on arrays. Additionally, it discusses fixed-bound subarrays and provides implementations for these problems.

Uploaded by

tusharsingh06.ts
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

DEPARTMENT OF

COMPUTER SCIENCE & ENGINEERING

Complex Problems for Fast Learner’s


Course Name: Advance Programming Lab – I
Subject Code: - (22CSP-314/22ITP-314)

Student Name: NEMESIS UID: 22BCSxxxxxx


Branch: BE-CSE Section/Group: 062/B
Semester: 5th Date of Performance:

Aim:
Trapping rainwater problem: Find the maximum amount of water that can be
trapped within a given set of bars where each bar’s width is 1 unit.
Code:

#include <bits/stdc++.h>
using namespace std;

int trapRainWater(int height[], int n) {


int left = 0, right = n-1, left_max = 0, right_max = 0, trapped = 0;
while(left < right){
if(height[left] < height[right]){
if(height[left] >= left_max) left_max = height[left];
else trapped += left_max - height[left];
left++;
}
else{
if(height[right] >= right_max) right_max = height[right];
else trapped += right_max - height[right];
right--;
}
}
return trapped;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

int main(){
int height[] = {7, 0, 4, 2, 5, 0, 6, 4, 0, 5};
int n = sizeof(height)/sizeof(height[0]);
cout << "The maximum amount of water that can be trapped is: " << trapRainWater(height,
n) << endl;
}

Ques 2:

You are given a 0-indexed integer array stations of length n, where stations[i] represents
the number of power stations in the ith city. Each power station can provide power to
every city in a fixed range. In other words, if the range is denoted by r, then a power
station at city i can provide power to all cities j such that |i - j| <= r and 0 <= i, j <= n - 1.
Note that |x| denotes absolute value. For example, |7 - 5| = 2 and |3 - 10| = 7. The power of
a city is the total number of power stations it is being provided power from. The
government has sanctioned building k more power stations, each of which can be built in
any city, and have the same range as the pre-existing ones. Given the two integers r and k,
return the maximum possible minimum power of a city, if the additional power stations
are built optimally.

Code:

#include <bits/stdc++.h>
using namespace std;
const int MAX = 100005;

long long computeInitialPower(int stations[], int power[], int n, int r) {


long long prefix[MAX] = {0};
for(int i=0;i<n;i++) prefix[i+1] = prefix[i] + stations[i];
for(int i=0;i<n;i++)
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

{
int L = max(0, i - r);
int R = min(n-1, i + r);
power[i] = prefix[R+1] - prefix[L];
}
return 0;
}

bool isPossible(long long mid, int power[], int n, int r, long long k) {
long long add_diff[MAX] = {0}, current_add = 0, additions = 0;
for(int i=0;i<n;i++) {
current_add += add_diff[i];
long long total = power[i] + current_add;
if(total < mid){
long long need = mid - total;
additions += need;
if(additions > k) return false;
int pos = min(n-1, i + r);
int L = max(0, pos - r);
int R = min(n-1, pos + r);
add_diff[L] += need;
if(R+1 < n) add_diff[R+1] -= need;
current_add += need;
}
}
return additions <= k;
}

long long maximizeMinimumPower(int stations[], int n, int r, long long k) {


int power[MAX];
computeInitialPower(stations, power, n, r);
long long left = 0, right = *max_element(power, power+n) + k;
while(left < right){
long long mid = left + (right +1 - left)/2;
if(isPossible(mid, power, n, r, k)) left = mid;
else right = mid -1;
}
return left;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

int main(){
// Example 1
{
int stations[] = {1,2,4,5,0};
int n = 5, r = 1;
long long k = 2;
cout << "Example 1 Output: " << maximizeMinimumPower(stations, n, r, k) << endl;
}
// Example 2
{
int stations[] = {4,4,4,4};
int n = 4, r = 0;
long long k = 3;
cout << "Example 2 Output: " << maximizeMinimumPower(stations, n, r, k) << endl;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

3. You are given two strings s and t. You are allowed to remove any number of
characters from the string t. The score of the string is 0 if no characters are removed from
the string t, otherwise: Let left be the minimum index among all removed characters. Let
right be the maximum index among all removed characters. Then the score of the string
is right - left + 1. Return the minimum possible score to make t a subsequence of s.
A subsequence of a string is a new string that is formed from the original string by
deleting some (can be none) of the characters without disturbing the relative positions of
the remaining characters. (i.e., "ace" is a subsequence of "abcde" while "aec" is not).

CODE:-

#include <bits/stdc++.h>
using namespace std;

const int MAX = 100005;

// Compute the prefix array: prefix[i] stores the earliest position in s where t[0..i] is a subsequence
void computePrefix(const char* s, int n, const char* t, int m, int prefix[]) {
int p = 0;
for(int i = 0; i < m; ++i){
while(p < n && s[p] != t[i]) p++;
if(p < n){
prefix[i] = p;
p++;
}
else{
for(int j = i; j < m; ++j) prefix[j] = -1;
break;
}
}
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

// Compute the suffix array: suffix[i] stores the latest position in s where t[i..m-1] is a subsequence
void computeSuffix(const char* s, int n, const char* t, int m, int suffix[]) {
int p = n-1;
for(int i = m-1; i >=0; --i){
while(p >=0 && s[p] != t[i]) p--;
if(p >=0){
suffix[i] = p;
p--;
}
else{
for(int j = i; j >=0; --j) suffix[j] = -1;
break;
}
}
}

int main(){
// Disable synchronization for faster I/O
ios::sync_with_stdio(false);
cin.tie(0);

// Define Test Cases


struct TestCase {
string s;
string t;
int expected_output;
};

TestCase test_cases[] = {
{"abacaba", "bzaa", 1},
{"cde", "xyz", 3}
};
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

int num_tests = sizeof(test_cases)/sizeof(TestCase);


for(int tc = 0; tc < num_tests; ++tc){
string s_str = test_cases[tc].s;
string t_str = test_cases[tc].t;
int expected = test_cases[tc].expected_output;

const char* s = s_str.c_str();


const char* t = t_str.c_str();
int n = s_str.length();
int m = t_str.length();

int prefix[MAX], suffix_arr[MAX];


memset(prefix, -1, sizeof(prefix));
memset(suffix_arr, -1, sizeof(suffix_arr));

computePrefix(s, n, t, m, prefix);
computeSuffix(s, n, t, m, suffix_arr);

// Check if t is already a subsequence of s


if(prefix[m-1] != -1){
cout << "Test Case " << tc+1 << " Output: " << 0 << "\n";
continue;
}

// Find the minimum window to remove


int ans = m;
int r =0;
for(int l =0; l < m; ++l){
if(prefix[l-1] == -1 && l !=0) continue;
while(r < m){
if(suffix_arr[r] != -1 && (l ==0 || suffix_arr[r] > prefix[l-1])){
break;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

r++;
}
if(r == m) break;
ans = min(ans, r - l +1);
}

// If ans wasn't updated, it means removing all characters is necessary


if(ans == m && (prefix[m-1] == -1)){
ans = m;
}

4. You are given two 0-indexed arrays nums1 and nums2 and a 2D array queries of queries. There are three
types of queries: For a query of type 1, queries[i] = [1, l, r]. Flip the values from 0 to 1 and from 1 to 0 in
nums1 from index l to index r. Both l and r are 0-indexed. For a query of type 2, queries[i] = [2, p, 0]. For
every index 0 <= i < n, set nums2[i] = nums2[i] + nums1[i] * p. For a query of type 3, queries[i] = [3, 0, 0].
Find the sum of the elements in nums2.Return an array containing all the answers to the third type queries.

Code:-

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 100005;
struct SegmentTree {
int tree[4 * MAX];
bool lazy[4 * MAX];
int n;
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

void init(int size) {


n = size;
memset(tree, 0, sizeof(tree));
memset(lazy, 0, sizeof(lazy));
}
void build(int idx, int l, int r, int nums1[]) {
if(l == r) {
tree[idx] = nums1[l];
return;
}
int mid = (l + r) / 2;
build(2*idx, l, mid, nums1);
build(2*idx+1, mid+1, r, nums1);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
void push(int idx, int l, int r) {
if(lazy[idx]) {
int mid = (l + r) / 2;
tree[2*idx] = (mid - l +1) - tree[2*idx];
lazy[2*idx] ^= 1;
tree[2*idx+1] = (r - mid) - tree[2*idx+1];
lazy[2*idx+1] ^= 1;
lazy[idx] = 0;
}
}
void update(int idx, int l, int r, int L, int R) {
if(R < l || L > r) return;
if(L <= l && r <= R) {
tree[idx] = (r - l +1) - tree[idx];
lazy[idx] ^= 1;
return;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

push(idx, l, r);
int mid = (l + r) / 2;
update(2*idx, l, mid, L, R);
update(2*idx+1, mid+1, r, L, R);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
int query(int idx, int l, int r, int L, int R) {
if(R < l || L > r) return 0;
if(L <= l && r <= R) return tree[idx];
push(idx, l, r);
int mid = (l + r) / 2;
return query(2*idx, l, mid, L, R) + query(2*idx+1, mid+1, r, L, R);
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
int nums1[MAX];
for(int i =0; i < n; i++) {
cin >> nums1[i];
}
ll nums2[MAX];
for(int i =0; i < n; i++) {
cin >> nums2[i];
}
SegmentTree st;
st.init(n);
st.build(1, 0, n-1, nums1);
ll total_ones = st.query(1, 0, n-1, 0, n-1);
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

ll sum_nums2 = 0;
for(int i =0; i < n; i++) {
sum_nums2 += nums2[i];
}
int q;
cin >> q;
ll *output = new ll[q];
int output_size = 0;
for(int i =0; i < q; i++) {
int type, a, b;
cin >> type >> a >> b;
if(type == 1){
ll ones_before = st.query(1, 0, n-1, a, b);
st.update(1, 0, n-1, a, b);
ll range_length = b - a +1;
ll ones_after = range_length - ones_before;
total_ones += (ones_after - ones_before);
}
else if(type == 2){
ll p = a;
sum_nums2 += p * total_ones;
}
else if(type ==3){
output[output_size++] = sum_nums2;
}
}
cout << "[";
for(int i =0; i < output_size; i++){
cout << output[i];
if(i != output_size -1) cout << ",";
}
cout << "]\n";
return 0;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

OUTPUT

5. You are given an integer array nums and two integers minK and maxK. A
fixed-bound subarray of nums is a subarray that satisfies the following conditions: The
minimum value in the subarray is equal to minK. The maximum value in the subarray is
equal to maxK. Return the number of fixed-bound subarrays.A subarray is a contiguous
part of an array.

CODE:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

int n;
cin >> n;
int nums[100005];
for(int i =0; i < n; i++) cin >> nums[i];
int minK, maxK;
cin >> minK >> maxK;
ll result = 0;
int last_min = -1, last_max = -1, last_invalid = -1;
for(int i =0; i < n; i++){
if(nums[i] < minK || nums[i] > maxK){
last_invalid = i;
}
if(nums[i] == minK){
last_min = i;
}
if(nums[i] == maxK){
last_max = i;
}
int current_min = min(last_min, last_max);
if(current_min > last_invalid){
result += (current_min - last_invalid);
}
}
cout << result;
return 0;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

6. - Given an array of integers heights representing the histogram's bar height


where the width of each bar is 1, return the area of the largest rectangle in the histogram.

CODE:

#include <bits/stdc++.h>
using namespace std;
// Function to calculate the largest rectangle area in a histogram
long long largestRectangleArea(vector<int>& heights) {
stack<int> st; // Stack to store indices
heights.push_back(0); // Append a zero to handle remaining bars
int n = heights.size();
long long max_area = 0;

for(int i = 0; i < n; i++) {


while(!st.empty() && heights[i] < heights[st.top()]) {
int top = st.top();
st.pop();
long long height = heights[top];
long long width = st.empty() ? i : (long long)(i - st.top() - 1);
max_area = max(max_area, height * width);
}
st.push(i);
}
return max_area;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cout << "Enter the number of histogram bars: ";
cin >> n;

vector<int> heights(n);
cout << "Enter the heights of the histogram bars separated by space:\n";
for(int i = 0; i < n; i++) {
cin >> heights[i];
}
long long result = largestRectangleArea(heights);
cout << "The area of the largest rectangle in the histogram is: " << result << "\n";
return 0;
}
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

OUTPUT

7. A path in a binary tree is a sequence of nodes where each pair of adjacent


nodes in the sequence has an edge connecting them. A node can only appear in the
sequence at most once. Note that the path does not need to pass through the root.
The path sum of a path is the sum of the node's values in the path.

CODE :
#include <bits/stdc++.h>
using namespace std;

struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
int max_sum;
Solution() : max_sum(INT32_MIN) {}
int maxPathSumHelper(TreeNode* root) {
if (root == nullptr) return 0;
int left = max(maxPathSumHelper(root->left), 0);
int right = max(maxPathSumHelper(root->right), 0);
int current_max = root->val + left + right;
max_sum = max(max_sum, current_max);
return root->val + max(left, right);
}

int maxPathSum(TreeNode* root) {


maxPathSumHelper(root);
return max_sum;
}
};
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

int main(){
ios::sync_with_stdio(false);
cin.tie(0);

TreeNode* root = new TreeNode(1);


root->left = new TreeNode(2);
root->right = new TreeNode(3);

Solution sol;
int result = sol.maxPathSum(root);

cout << "The maximum path sum of the binary tree is: " << result << "\n";

delete root->left;
delete root->right;
delete root;

return 0;
}

OUTPUT:

You might also like