diff --git a/1001/en.md b/1001/en.md new file mode 100644 index 00000000..cdb7ed70 --- /dev/null +++ b/1001/en.md @@ -0,0 +1,52 @@ +# LOJ 1001 - Opposite Task + +In this problem, you are given `T` test cases. Each test case contains an integer `n`, the value of which is `20` at max. Your task is to print out two non-negative integers `a` and `b`, such that `n = a + b`. Any values of `a` and `b` that satisfies the equation is accepted, however, neither of `a` nor `b` can be greater than `10`. + +It is one of the easiest problems on LightOJ volumes. However, some people might find it difficult to get an `Accepted` verdict. The reason could be one of the following: +1. Printing a number greater than 10 +2. Failing to provide proper output format +3. Missing new line on each line + +If you are still stuck with this problem, check the codes below: + +### C +----- +```c +#include +int main() { + int T, n; + scanf("%d", &T); + for (int i = 1; i <= T; i++) { + scanf("%d", &n); + if (n > 10) { + printf("10 %d\n", n - 10); + } else { + printf("0 %d\n", n); + } + } + return 0; +} +``` + +### Java +----- +```java +package com.loj.volume; + +import java.util.Scanner; + +class OppositeTask { + public static void main(String[] args) throws Exception { + Scanner scanner = new Scanner(System.in); + int T = scanner.nextInt(), n; + for (int i = 1; i <= T; i++) { + n = scanner.nextInt(); + if (n > 10) { + System.out.printf("10 %d\n", n - 10); + } else { + System.out.printf("0 %d\n", n); + } + } + } +} +``` diff --git a/1007/en.md b/1007/en.md new file mode 100644 index 00000000..4e20d95c --- /dev/null +++ b/1007/en.md @@ -0,0 +1,80 @@ +# LOJ 1007 - Mathematically Hard + +_You have given `T` test cases and for each test case you have `a`, the lower bound, and `b`, the upper bound, find the summation of the +scores of the numbers from a to b (inclusive), where
+score (x) = n2,where n is the number of relatively prime numbers with x, which are smaller than x._ + +--- + +### Summary + +This is a number theory problem and for the `T` group of the input set, where each set consists of `a` and `b`, you have to find,square sum of all Euler function values from `a` to `b`. + +### Solution + +Before you get to the solution let's have some idea about `Euler's totient function` aka `phi`.
+ +``` +Euler's totient function, also known as phi-function `ϕ(n)`, counts the number of integers between `1` and `n` inclusive, which are `coprime` to `n`. Two numbers are coprime if their greatest common divisor equals `1` (`1` is considered to be coprime to any number). +``` + +Have a look: + +- [wikipedia: Euler's totient function](https://en.wikipedia.org/wiki/Euler%27s_totient_function) +- [cp-algorithms: Euler's totient function](https://cp-algorithms.com/algebra/phi-function.html) + +- [A quite useful cheat-sheet of CP: Phi Implementation](https://github.com/ar-pavel/CP-CheatSheet#631-euler-function) + +Using Euler's totient function, calculate number of coprime for all the numbers until max possible input. Now, let's assume you have `phi[]` array that contains all the `ϕ(n)` values. As you will need to print the sum of square values of the `ϕ(n)`, loop through the `phi[]` array and multiply them with own value (`phi[i] = phi[i]*phi[i]`). Now your `phi[]` array contains square values of each `ϕ(n)`. For each query, as you need to print `sum(phi[a] ... phi[b])`, you can optimize this process by generating a [cumulative sum array](https://www.tutorialspoint.com/cplusplus-program-for-range-sum-queries-without-updates) of of `phi[]`. + +The algorithm is: + +- find all Phi values from `1 - rangeMax` +- calculate square value of each of them +- generate cumulative sum array of squared phi values +- for each query, print the `cumulative sum array[b]` - `cumulative sum array [a-1]` + +### C++ +----- +```cpp +#include + +using namespace std; + +#define M 5000000 + +int phi[M+2]; +unsigned long long phiSum[M+2]; + +void calculatePhi(){ + for(int i=2; i<=M; i++) + phi[i] = i; + for(int i =2; i<=M; i++) + if(phi[i]==i) + for(int j=i; j<=M; j+=i) + phi[j]-=phi[j]/i; +} + +int main(){ + + calculatePhi(); + phiSum[1] = 0; + + for(int i=2; i<=M; i++) + phiSum[i]= ((unsigned long long)phi[i]* (unsigned long long)phi[i])+phiSum[i-1]; + + // for(int i=1; i<10; ++i) + // cout< + + using namespace std; + + int main(){ + #ifndef ONLINE_JUDGE + freopen("in.txt","r",stdin); + freopen("out.txt","w",stdout); + #endif + + int tc,t(1); + for(scanf("%d",&tc); tc; ++t,--tc){ + long long piaju,left; + + scanf("%lld%lld", &piaju,&left); + + // exception + if(left*2>=piaju){ + printf("Case %d: impossible\n",t); + continue; + } + + printf("Case %d:",t); + + + long long piajuEaten = piaju-left; + // cout< possibleValueOfQ; + + + // find all the divisors of piajuEaten + for(long long i=1; i*i<=piajuEaten; ++i) + if(piajuEaten%i==0){ + possibleValueOfQ.push_back(i); + + if(piaju/i!=i) + possibleValueOfQ.push_back(piajuEaten/i); + } + + // sort the divisors to print the answer in ascending order + sort(possibleValueOfQ.begin(), possibleValueOfQ.end()); + + // print the divisors + for(auto x: possibleValueOfQ) + // if(x>left) + printf(" %lld",x); + + + printf("\n"); + } + + return 0; + } + +``` diff --git a/1029/en.md b/1029/en.md new file mode 100644 index 00000000..b6cc328e --- /dev/null +++ b/1029/en.md @@ -0,0 +1,146 @@ +# LOJ 1029 - Civil and Evil Engineer + +### Problem Summary + +You have `n` houses `[1-n]` and a power station `0`. You are also given a set of wires, where every wire is in `u v w` format, meaning `connection from u to v costs w`. You have to use exactly `n` wires from the set to connect the houses with the power station. **The connections can be direct or indirect (through some houses) but there must be a path of wires from every house to the power station.** + +### Observations + +We can see the following properties in the problem structure. + +- **Graph**: We can consider the houses and the power station as `nodes` in a graph, and the wires as `edges`. Since the costs of connecting two nodes are given, and the connections have no direction, so this is a `Weighted Undirected Graph`. + +- **Tree**: In total, we have `n+1` nodes (`n` houses and `1` power station). We have to connect them using exactly `n` wires or `edges`. We know in a tree, for `N` nodes we have `N-1` edges. So the problem is asking us to convert the graph into a tree. + +- **Minimum Spanning Tree**: For the `best possible connection scheme`, We have to connect all houses with the power station using minimum cost. We have to pick `edges` in a way that satisfies the cost minimization. Therefore, we have to compute the `Minimum Spanning Tree` of the graph. + + - `Minimum Spanning Tree` of a graph is a subtree of that graph that contains all the `nodes` and the `sum of edge weights` is minimum possible. You can use [Prim's algorithm](https://cp-algorithms.com/graph/mst_prim.html) or [Kruskal's Algorithm](https://cp-algorithms.com/graph/mst_kruskal.html) to implement the Minimum Spanning Tree. + +- **Maximum Spanning Tree**: We also have to calculate the maximum possible cost to connect all the `nodes`, since this is the `worst possible connection scheme`. For this, we have to pick `edges` in a way that maximizes the cost. So we also have to compute the `Maximum Spanning Tree` of the graph. + - `Maximum Spanning Tree` of a graph is a subtree of that graph that contains all the `nodes` and the `sum of edge weights` is maximum possible. We can tweak the Minimum Spanning Tree algorithm (sort the edges in descending order of the weights) to implement Maximum Spanning Tree. + +### Solution + +For every case, we have to calculate minimum spanning tree `cost1` and maximum spanning tree `cost2` and then average their costs, thus `(cost1 + cost2) / 2`. If `(cost1 + cost2)` is not divisible by `2` then we have to print in `p/q` format. Where `p` is `(cost1 + cost2)` and `q` is `2`. For example, `229/2`. + +### Simulation + +Simulation of **test case 2** is given below. + +![Frame 1](https://user-images.githubusercontent.com/14056189/99875765-3bdd5700-2c1c-11eb-970f-92222ebe7c22.png) + +![Frame 2](https://user-images.githubusercontent.com/14056189/99876684-8792ff00-2c22-11eb-8a0a-6fe3ee6bc73f.png) + +![Frame 3](https://user-images.githubusercontent.com/14056189/99875768-3f70de00-2c1c-11eb-80d2-38ab56236789.png) + +And the answer is `(70 + 159) / 2`. Since `229` is not divisible by `2`, we print `229/2`. + +### C++ + +--- + +```C++ +#include +using namespace std; + +struct edge{ + int u, v, w; +}; + +bool cmp(edge A, edge B){ + return A.w < B.w; +} + +// edge list +vector < edge > G; + +int n; // total nodes +int parent[105]; + +// function to clear graph +void _init(){ + G.clear(); +} + +// function to find parent of a disjoint set +int Find(int u){ + if (u==parent[u]) return u; + return parent[u] = Find(parent[u]); +} + +// Kruskal's algorithm with Disjoint-Set Union method is used +// minimum spanning tree +long long MinST(){ + // reset parent table [0-n] + for (int i = 0; i <= n; i++) + parent[i] = i; + + long long cost = 0; + // forward iteration for minimum cost first + for (int i = 0; i < G.size(); i++){ + int u = G[i].u; + int v = G[i].v; + int w = G[i].w; + + int p = Find(u); + int q = Find(v); + if (p!=q){ + cost += w; + parent[q] = p; + } + } + return cost; +} + +// maximum spanning tree +long long MaxST(){ + // reset parent table [0-n] + for (int i = 0; i <= n; i++) + parent[i] = i; + + long long cost = 0; + // backward iteration for maximum cost first + for (int i = G.size()-1; i >= 0; i--){ + int u = G[i].u; + int v = G[i].v; + int w = G[i].w; + + int p = Find(u); + int q = Find(v); + if (p!=q){ + cost += w; + parent[q] = p; + } + } + return cost; +} + +int main() +{ + int T; scanf("%d", &T); + for (int cs = 1; cs <= T; cs++){ + _init(); // reset graph + + scanf("%d", &n); + int u, v, w; + + // take input until all u, v, w are zero (0) + while ( scanf("%d%d%d", &u, &v, &w) && (u!=0 || v!=0 || w!=0) ){ + G.push_back({u, v, w}); + } + + // sorting is only done once + // forward and backward iterations will be done + // for ascending and descending order traversal + sort(G.begin(), G.end(), cmp); + + long long cost1 = MinST(); + long long cost2 = MaxST(); + + long long cost = cost1 + cost2; + if (cost%2 == 0) printf("Case %d: %lld\n", cs, cost/2); + else printf("Case %d: %lld/2\n", cs, cost); // cost/2 format + } + return 0; +} +``` diff --git a/1062/1.png b/1062/1.png new file mode 100644 index 00000000..a8769f02 Binary files /dev/null and b/1062/1.png differ diff --git a/1062/2.jpg b/1062/2.jpg new file mode 100644 index 00000000..9ea9b2af Binary files /dev/null and b/1062/2.jpg differ diff --git a/1062/3.jpg b/1062/3.jpg new file mode 100644 index 00000000..05b9db88 Binary files /dev/null and b/1062/3.jpg differ diff --git a/1062/en.md b/1062/en.md new file mode 100644 index 00000000..4d4d5ca4 --- /dev/null +++ b/1062/en.md @@ -0,0 +1,108 @@ +# 1062 - Crossed Ladders : + +A ladder with length **X** rested from the base and lean with the right building. Another ladder with length **Y** rested from another right side's base and lean with the left side's base. These two ladders are crossed at a point **N**. The length between **M** and **N** is **h**. We have to find the width **d** of the road. + +In this problem, you are given **T** testcases to execute. For each test case you will be given **X**, **Y** and **h**. You have to find the value of **d** for every single test cases. + +#### Tutorial : +![1](https://user-images.githubusercontent.com/14172268/100465297-3e96eb00-30f9-11eb-9319-aeb3ef3653fb.png) + +In the crossed ladder problem two ladder ```AC``` and ```BD``` crossed each other at point ```N```. The length of ```AC``` and ```BD``` is ```X``` and ```Y``` respectively. You are also given the value of length ```h```. Let's denote ```AB = h1``` , ```CD = h2```, ```AD = d``` . From these values, we can find out the value of ```d```. Using basic observation it is pretty clear that the value of ```d``` will always be less than the values of ```X``` and ```Y```. You can apply a bisection over this ```d``` length to get a nearly correct result. + +From the theory of crossed ladder problem we can say that , + + + +See the images below for further clarifications about the equation. + +![2](https://user-images.githubusercontent.com/14172268/100465309-422a7200-30f9-11eb-904e-ae0af63f16d4.jpg) ![3](https://user-images.githubusercontent.com/14172268/100465313-45256280-30f9-11eb-9096-29935a9f0803.jpg) + +Hence We have the proof about the equation. + +Now, we can start the bisection by denoting the parameters ```low = d = 0``` and ```high = d = minimum(X, Y)```. Every time we have to find the ```mid``` value between ```low``` and ```high```. A nice property that lies in the crossed ladder problem is when the width ```d``` increases the height ```h``` decreases and vice versa. That means from several ```mid``` values of width we just have found such a value that will fairly equal to ```h```. + +Let the ```mid = K``` ( in general d ) and you have the value of ```X```. From pythagorean theorem, we know, + +![1](https://user-images.githubusercontent.com/14172268/100466281-e365f800-30fa-11eb-8672-fb33477dfad4.jpg) + +From this equation, We can show that - + +![2](https://user-images.githubusercontent.com/14172268/100466284-e3fe8e80-30fa-11eb-9f46-807eea4dd634.png) + +![3](https://user-images.githubusercontent.com/14172268/100466286-e4972500-30fa-11eb-8348-b27e4d24bc8a.png) + +So, now you have the value of ```h1``` and ```h2``` . You can easily find , + +![4](https://user-images.githubusercontent.com/14172268/100466279-e234cb00-30fa-11eb-9e79-38b4d404fbb8.png) + +For a value of ```mid```, we will found the approximate value of real ```h```. Now for every calculated ```h```, you easily can compare with the original ```h```. + + +# Code +```c++ +#include +#define DIST(x1,x2, y1, y2) (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))) +#define CLR(a) a.clear() +#define VCLR(a, n) for(int i=0; i<=n+3; i++) a[i].clear() +#define SIZE(a) a.size() +#define ERASE(a, b) memset(a, b, sizeof a) +#define PB(a, b) a.push_back(b) +#define PB2(a,i,b) a[i].push_back(b) +#define LL long long +#define DBG cout<<"I Am Here"< +#define MAX 600005 +#define CASE(i) printf("Case %d: ", i); +#define PI acos(-1) +#define EPS 0.00000001 + +using namespace std; + +double x, y, c; + +double solve(double mid) +{ + double A = sqrt((x*x) - (mid*mid)); + double B = sqrt((y*y) - (mid*mid)); + + //cout<id +1 2 3 4 5 --->there relative position +আমাদেরকে ২ ধরনের কুয়েরী করা হবেঃ + +**ধরন ১:** +a 20 +এটা মানে এখন যারা দাঁড়িয়ে আছে তাদের শেষে এই 20 আইডিযুক্ত লোক্টি দাঁড়াবে। এবং তাদের সবার রিলেটিভ অর্ডার হবে +6 5 3 2 1 20 --->id +1 2 3 4 5 6 --->there relative position + +**ধরন ২:** +c 3 +৩ নাম্বারে থাকা লোকটিকে ডাকা হলো এবং সে তার পজিশন থেকে বের হয়ে যাবে।এই ধরনের কুয়েরীর জন্য আপনাকে লেফট সাইড থেকে অই পজিশনে থাকা লোকের আইডি নাম্বার প্রিন্ট করাতে হবে। এখানে এন্সার হবে ৩ কারন লেফট সাইড থেকে ৩ আইডি যুক্ত লোকটি ৩ নাম্বার রিলেটিভ পজিশনে ছিলো। +এখন তাদের সবার রিলেটিভ অর্ডার হবেঃ +6 5 2 1 20 --->id +1 2 3 4 5 --->there relative position + + +**অবসার্ভেশন ১:** +আমাদের সর্বোমোট কুয়েরী সংখ্যা হইতে পারে ৫০০০০ টি। তার মানে আমাদের লিস্টে সর্বোমোট ১০০০০০ + ৫০০০০ জন নতুন করে পিছন দিকে এসে দাড়াতে পারবে। + +**অবসার্ভেশন ২:** +প্রত্যেক মানুষের রিলেটিভ পজিশন হলো তার আগে যত জন মানুষ আছে + ১। +**এক্সপ্লেইনেশনঃ** +ধরি,যারা দাঁড়িয়ে আছে তাদের পজিশনের ভ্যালু ১ এবং যারা বের হয়ে যাচ্ছে তাদের পজিশনের ভ্যালু ০। তাহলে শুরুতে আমাদের এরে দেখতে যেমন দেখাবেঃ +1 1 1 1 1 +1 2 3 4 5 + +প্রথম কুয়েরীর পর যেমন দেখাবেঃ +1 1 1 1 1 1 +1 2 3 4 5 6 + +দ্বিতীয় কুয়েরীর পর যেমন দেখাবেঃ +1 1 0 1 1 1 +1 2 3 4 5 6 + +এখন যদি জিজ্ঞেস করা হয় যে, ৫ম পজিশনে থাকা লোকের রিলেটিভ পজিশন কত? উত্তর হবে ৪। কিভাবে উত্তর পেলাম? +একটু খেয়াল করলে দেখা যায়,এই আর‍্যের প্রেফিক্স যেটি ৫ম পজিশনে এসে শেষ হয়েছে তার যোগফল ৪। এভাবেই আমরা রিলেটিভ পজিশন বের করতে পারি। তো আমাদের , এই রিলেটিভ পজিশন দেওয়া থাকবে আমাদের বলতে হবে এই পজিশনে কে আছে। সেটাই অউটপুট হিসাবে প্রিন্ট করাতে হবে। তো আমরা যদি ২য় ধরনের কুয়েরীর এর সময় এই প্রেফিক্স এরে টা জানি,তাহলে আমাদের দেখতে হবে সবচেয়ে বামের এই রিলেটিভ পজিশনে কে আছে। + +দ্বিতীয় কুয়েরীর পর প্রেফিক্স এরে টা যেমন দেখাবেঃ +1 2 2 3 4 5 +1 2 3 4 5 6 + +এই প্রেফিক্স এরে টা মেনটেইন করার জন্য আমরা [সেগমেন্ট ট্রী](https://cp-algorithms.com/data_structures/segment_tree.html) অথবা [বাইনারী ইন্ডেক্সট ট্রী](https://www.youtube.com/watch?v=CWDQJGaN1gY&t=447s) ব্যবহার করতে পারি। আর প্রেফিক্স সাম যেহেতু একটা মনোটনিক ফাংশন,আমরা এর উপর বাইনারী সার্চ চালিয়ে সবচেয়ে বামের রিলেটিভ পজিশন বের করতে পারি এবং অই পজিশনে যে লোকটি দাঁড়িয়ে থাকবে তার আইডিই আমাদের প্রব্লেম এর এন্সার। + +**Note: use fast I/O :3** +If you are still stuck with this problem, check the codes below: + +### C++ +----- +```cpp +#include +using namespace std; +const int maxx=150005; +int BIT[maxx]; + +void update(int pos,int val){ + while(pos<=maxx-1){ + BIT[pos]+=val; + pos+=(pos&-pos); + } +} + +int query(int pos){ + int res=0; + while(pos>0){ + res+=BIT[pos]; + pos-=(pos&-pos); + } + return res; +} + +void solve(){ + memset(BIT, 0, sizeof(BIT)); + int n,q; + scanf("%d%d",&n,&q); + vector vec(maxx); + for(int i=1;i<=n;i++){ + scanf("%d",&vec[i]); + update(i,1); + } + getchar(); + int en=n; + for(int i=0;i=x){ + if(xx==x) ans=mid; + high=mid-1; + } + else lo=mid+1; + } + if(ans==-1) printf("none\n"); + else { + printf("%d\n",vec[ans]); + update(ans,-1); // Because the person who was standing at that ans position will come out and leave that position + vec[ans]=-1; // void. So,# of person will decrease by 1. + } + } + else { + scanf("%d",&x);getchar(); + vec[++en]=x; + update(en,1); + } + } +} + +signed main() +{ + int t; + scanf("%d",&t); + int cs=0; + while(t--){ + printf("Case %d:\n",++cs); + solve(); + } + return 0; +} +``` \ No newline at end of file diff --git a/1087/en.md b/1087/en.md new file mode 100644 index 00000000..ba0de4c1 --- /dev/null +++ b/1087/en.md @@ -0,0 +1,130 @@ +# LOJ 1087 - Diablo + +Starting with an example to understand the problem better.Suppose, we have n people standing linearly and everyone has assigned with an ID: +6 5 3 2 1 --->ID +1 2 3 4 5 --->there relative position. +We will have two queries: + +**For type 1:** +a 20 +People with ID 20 will stand next to the last people standing already.The relative order of the list will be: +6 5 3 2 1 20 --->ID +1 2 3 4 5 6 --->there relative position. +**For type 2:** +c 3 +People who is standing in the 3rd position from the left will be called out and for this type of query ,you need to print the ID of that people.Here,the ans is 3 and after this query the relative order of the list will be: +6 5 2 1 20 --->ID +1 2 3 4 5 --->there relative position. + +**Observation 1:** +Number of q could be at most 50000 and initial number of people could be 100000. So for 1st type of query,we can observe that overall there could be at most 150000 people at a time. +**Observation 2:** +relative position of every people is the number of people standing right before him/her + 1. + +**Explanation:** +Lets say,people standing in the array means his/her positional value is 1 and people called out means his/her positional value in that list is 0. In our example,replacing with the value of the people ,initial array will look like, +1 1 1 1 1 +1 2 3 4 5 + +After query type 1,array will look like +1 1 1 1 1 1 +1 2 3 4 5 6 +After query type 2,array will look like +1 1 0 1 1 1 +1 2 3 4 5 6 + + +Now,if we are asked what is the relative position of the people standing 5th position? +Ans will be 4. How can we calculate it? +Well, the prefix ends in 5th position has the sum 4,that is how,we can find the relative position of any people standing anywhere. +The prefix sum array will look like, +1 2 2 3 4 5 +1 2 3 4 5 6 + +The actual problem will give you the relative position of a people and you need to output the ID of that people who has the relative position the problem asked for and of course the left most occurrence of that relative position is the ans. + +So,for prefix sum query and update we can use any range query data structure such as [Segment Tree](https://cp-algorithms.com/data_structures/segment_tree.html),[Binary Indexed Tree](https://www.youtube.com/watch?v=CWDQJGaN1gY&t=447s). +As,prefix sum array is a monotonic array,we can binary search for the leftmost occurrence of the relative position the problem will ask for. + +**Note: use fast I/O :3** +If you are still stuck with this problem, check the codes below: + +### C++ +----- +```cpp +#include +using namespace std; +const int maxx=150005; +int BIT[maxx]; + +void update(int pos,int val){ + while(pos<=maxx-1){ + BIT[pos]+=val; + pos+=(pos&-pos); + } +} + +int query(int pos){ + int res=0; + while(pos>0){ + res+=BIT[pos]; + pos-=(pos&-pos); + } + return res; +} + +void solve(){ + memset(BIT, 0, sizeof(BIT)); + int n,q; + scanf("%d%d",&n,&q); + vector vec(maxx); + for(int i=1;i<=n;i++){ + scanf("%d",&vec[i]); + update(i,1); + } + getchar(); + int en=n; + for(int i=0;i=x){ + if(xx==x) ans=mid; + high=mid-1; + } + else lo=mid+1; + } + if(ans==-1) printf("none\n"); + else { + printf("%d\n",vec[ans]); + update(ans,-1); // Because the person who was standing at that ans position will come out and leave that position + vec[ans]=-1; // void. So,# of person will decrease by 1. + } + } + else { + scanf("%d",&x);getchar(); + vec[++en]=x; + update(en,1); + } + } +} + +signed main() +{ + int t; + scanf("%d",&t); + int cs=0; + while(t--){ + printf("Case %d:\n",++cs); + solve(); + } + return 0; +} +``` \ No newline at end of file diff --git a/1129/en.md b/1129/en.md new file mode 100644 index 00000000..e8a6749d --- /dev/null +++ b/1129/en.md @@ -0,0 +1,132 @@ +# LOJ 1129 - Consistency Checker + +In this problem, you will be given `T` testcases. The first line of each test case contains an integer `n`. Following `n` lines will contain a number of length `1-10` each. You are asked to check the consistency of the dataset. The consistency is, no number is a prefix of another number. + +To recap, a substring of a string from its `0th` index is a prefix of that string. Like `123` is a prefix of `12345`, but `124`, `234`, or `132` is not. + +This is a great problem to start **Trie Data Structure** if you haven't already. +**Tries** are an extremely special and useful data-structure that are based on the prefix of a string. They are used to represent the **“Retrieval”** of data. + +Here are some resources to trie data structure you can understand and learn:- + +- [Shafaetsplanet](http://www.shafaetsplanet.com/?p=1679) +- [HackerRank](https://m.youtube.com/watch?v=zIjfhVPRZCg&list=PLI1t_8YX-Apv-UiRlnZwqqrRT8D1RhriX&index=9&t=1s) +- [Tushar Roy - Coding Made Easy](https://m.youtube.com/watch?v=AXjmTQ8LEoI) + +### Approach: + +Atfirst, we create a trie for each new testcase. A single node of trie data structure will contain a `boolean` variable and an `array` of trie nodes of length `10`. The boolean variable will say if a string end on that node or not. The `10` size array will be enough for the next adjacent digit of the number because different digits can be atmost ten `(0-9)`. + +The best way to take input of the `n` numbers for each testcase is as strings. Because trie deals with the prefix of a string. If we want to take `n` numbers as integers, we can. Because `integer` data type can hold between `-2147483648` to `+2147483647` which will be enough to hold an integer of length `1-10`. But still that won't be a smart approach. + +So we simply take the `n` input numbers as strings and insert into the trie. Once the trie is formed, we create a function `isPrefix()` which will check if there is a single number prefix of another number or not in the trie. How will the function check? The function will traverse the trie, and if there is a single node which has the boolean variable value `true` but more trie nodes emit from that node, this confirms that it is a prefix. + +Example, if our trie consists of two numbers `123` and `12345`, at the node for digit `3`, there is a number ending but still more node coming out from it. So, this confirms that the dataset is not consistent. + +Visualization- +``` +//A trie with two strings inserted, "123" and "12345" + + 1(false) + \ + 2(false) + \ + 3(true) <-- ending of string "123" but not the leaf node! + \ + 4(false) + \ + 5(true) <-- ending of string "12345" and it is a leaf node +``` + +Lastly, after the answer is got, we delete the trie from the memory to avoid memory wastage in our program. + +Try yourself before watching the code below. + +### C++: + +```cpp +#include +#include +using namespace std; + +///Trie/Radix Tree + +struct trie +{ + bool endmark; //boolean variable to mark end of number + trie *arr[10]; //10length array of trie nodes for 0-9 + //constructor + trie() + { + endmark = 0; + for(int i=0; i<=9; i++) + { + arr[i] = NULL; + } + } +} * root; //globally declaring variable of the struct + +void insert(char s[]) +{ + int n = 0; + for( ; s[n]; n++) {} //size() + + trie *curr = root; + for(int i=0; iarr[x]==NULL) curr->arr[x] = new trie(); + curr = curr->arr[x]; + } + curr->endmark = 1; +} + +void del(trie* node) +{ + for(int i=0; i<10; i++) + { + if(node->arr[i]!=NULL) //recursive del! + del(node->arr[i]); + } + delete(node); +} + +bool isPrefix(trie *node) +{ + for(int i=0; i<=9; i++) + { + if(node->arr[i]!=NULL) + { + if(node->endmark) return 1; + if(isPrefix(node->arr[i])) return 1; + } + } + return 0; +} + +int main() +{ + int t=0,tc=0; + scanf(" %d", &tc); + for(t=1; t<=tc; t++) //testcase + { + int i=0, j=0; + root = new trie(); //creating the trie for this testcase + + int n; //no. of numbers + scanf(" %d", &n); + char s[10]; + while(n--) + { + scanf(" %s",&s[0]); //taking number as string + insert(s); //inserting string into the trie + } + + // The function determining the YES or NO as answer! + isPrefix(root)? printf("Case %d: NO\n",t) : printf("Case %d: YES\n",t); + + del(root); //destroying the trie each time after a testcase ends to not hold memory anymore + } + return 0; +} +``` diff --git a/1136/en.md b/1136/en.md new file mode 100644 index 00000000..6b90ef09 --- /dev/null +++ b/1136/en.md @@ -0,0 +1,138 @@ +# LOJ 1136 - Division by 3 + +## Problem +Straight from the statement: "There is sequence 1, 12, 123, 1234, ..., 12345678910, ... . Now you are given two integers **A** and **B**, you have to find the number of integers from **A**th number to **B**th (inclusive) number, which are divisible by 3. + +For example, let **A** = 3. **B** = 5. So, the numbers in the sequence are, 123, 1234, 12345. And 123, 12345 are divisible by 3. So, the result is 2." + +Looking a bit into the sequence you will find out that for a certain position **A** the number can be found by simply appending all natural numbers from 1 upto **A** one after another. So if **A** = 5: sequence is 12345, if **A** = 12: sequence is 123456789101112. + +Now you will be given two numbers **A** and **B**. You have to find out how many numbers on that sequence are divisible by 3 on the position of **A**, **A+1**, ..., **B** (from position **A** to position **B** inclusive). + +## Constrains: +Test cases T (≤ 10000) and 1 ≤ A ≤ B < 2^31 + +## Observation +1. By looking at the constrains, it is quite sure that bruteforce approach is going to gift us TLE. (If you calculate all the number from range **A** to **B** and try to find out who amoung them are divisible by 3 you will get time limit exceeded). So we need a very effecient approach. +2. Numbers can be quite big. + +## Understanding 1 +Let get our hands dirty by finding out if numbers from the sequence are divisible by 3. + +| Position at the sequence | Number | Is divisible by 3 | +|--------------------------|-------------|-------------------| +| 1 | 1 | false | +| 2 | 12 | true | +| 3 | 123 | true | +| 4 | 1234 | false | +| 5 | 12345 | true | +| 6 | 123456 | true | +| 7 | 1234567 | false | +| 8 | 12345678 | true | +| 9 | 123456789 | true | +| 10 | 12345678910 | false | + +We can clearly see a repeatitive pattern. Here {1, 4, 7, 10...} positions are not divisible by 3 and rests are. + +Curious minds will want to know "why?". Simple! + +First, you may know that calcuting if a number is divisible by 3 is super easy. You just add all digits and see if the sum is divisible by 3 or not. So finding out if 123456 is divisible by 3 is equal to finding out if (1 + 2 + 3 + 4 + 5 + 6) = 21 is divisible by 3 or not. + +Now focus on the table. Each time we construct new position we just add the position-number to the previous value of the sequence, right? Let's follow an example. We have found out the 5th position in this sequence is 12345 which is divisible by 3 (12345 % 3 = 0; 12345 modulo 3 is zero. Also in other words (1 + 2 + 3 + 4 + 5) % 3 = 0). Now we construct 6th position in the sequence by just appending 6 to the last of the 5th number (123456). To calcuate if new number is divisible by 3 we can check that (1 + 2 + 3 + 4 + 5 + 6) % 3 is equal to 0 or not. Now after messing with paranthesis, you can see that (1 + 2 + 3 + 4 + 5 + 6) % 3 = ( (1 + 2 + 3 + 4 + 5) + 6) % 3. In other words for every **n***, *seq[n]** % 3 = (**seq[n - 1]** + n) % 3 = (**seq[n - 1]** % 3 + n % 3) % 3 (From modular arithmatic). + +Now look at this table: +| Position at the sequence | Number | Number % 3 | Previous_number % 3 | Position % 3 | (Previous_number % 3 + Position % 3) % 3 | +|--------------------------|-------------|------------|---------------------|--------------|------------------------------------------| +| 1 | 1 | 1 | - | 1 | Default value to 1 | +| 2 | 12 | 0 | 1 | 2 | ( 1 % 3 + 2 % 3) % 3 = 0 | +| 3 | 123 | 0 | 0 | 0 | ( 0 % 3 + 0 % 3) % 3 = 0 | +| 4 | 1234 | 1 | 0 | 1 | ( 0 % 3 + 1 % 3) % 3 = 1 | +| 5 | 12345 | 0 | 1 | 2 | ( 1 % 3 + 2 % 3) % 3 = 0 | +| 6 | 123456 | 0 | 0 | 0 | ( 0 % 3 + 0 % 3) % 3 = 0 | +| 7 | 1234567 | 1 | 0 | 1 | ( 0 % 3 + 1 % 3) % 3 = 1 | +| 8 | 12345678 | 0 | 1 | 2 | ( 1 % 3 + 2 % 3) % 3 = 0 | +| 9 | 123456789 | 0 | 0 | 0 | ( 0 % 3 + 0 % 3) % 3 = 0 | +| 10 | 12345678910 | 1 | 0 | 1 | ( 0 % 3 + 1 % 3) % 3 = 1 | + +Does the pattern make sense now? + +## Understanding 2 +Previous undestanding is not enough to give you an AC, right? Now Let's look at the table a bit differently. Now we will add cumulative sum too and replace true/false with one/zero. + +| Position at the sequence | Number | Is divisible by 3 | Cumulative sum over divisibility | +|--------------------------|-------------|-------------------|----------------------------------| +| 1 | 1 | 0 | 0 | +| 2 | 12 | 1 | 1 | +| 3 | 123 | 1 | 2 | +| 4 | 1234 | 0 | 2 | +| 5 | 12345 | 1 | 3 | +| 6 | 123456 | 1 | 4 | +| 7 | 1234567 | 0 | 4 | +| 8 | 12345678 | 1 | 5 | +| 9 | 123456789 | 1 | 6 | +| 10 | 12345678910 | 0 | 6 | + +Here cumulative sum for position **n** simply says "Between position 1 to **n** how many numbers are divisible by 3". Now can you tell how many numbers are divisible by 3 from position 4 to 7? We simply take the cumulative sum of position 7 and substract cumilative sum of position 3 (Because cumulative sum for position 7 says how many number are divisible by 3 from position 1 to 7, and we just substract how many numbers where divisible by 3 before the 4rth position). + +## Understanding 3 +Now we know that cumulative sum can be the key to success. We just have to find it smartly. By looking at the last table we can get that {1, 4, 7, 10, ...} are not divisible by 3. And all this positions are also 1 modulo 3 (position % 3 = 1). So if we get a position which is 1 modulo 3 it will not be divisible, right? (If position % 3 = 1 then not divisible by 3.) + +Now, finding out how many numbers are divisible by 3 from 1 to **n** is quite equal to finding how many numbers are not divisible by 3 and substract the answer from **n**. (numbers_divisible_by_3_from_1_to_n = n - numbers_not_divisible_by_3). Now our problem has become smaller. Here we can see that for every three consecutive position starting from 1, first position is not divisible by 3. So to calculate how many numbers are not divisible by 3 in range of position 1 to **n**... +1. If n % 3 = 0 then exactly (n / 3) integers are not divisible by 3. +2. If n % 3 = 1 then exactly floor(n / 3) + 1 integers are not divisible by 3. +3. If n % 3 = 2 then exactly floor(n / 3) + 1 integers are not divisible by 3. +So now we will get how many numbers are divisible by 3 by simply substracting the result found above from the number **n**. + +c++ function to calculate this is going to be (Beware of n = 1 case also)... +``` +long long numbers_divisible_by_3_from_1_to_n (int n){ + if(n == 0) return 0; // Caution: we will also call numbers_divisible_by_3_from_1_to_n(A - 1). If A = 1 then the argument becomes -1 which can result in + // calculation. + int subs; + if(n % 3 == 0) { + subs = n / 3; + } else { // both n % 3 == 1 and n % 3 == 2 shows the same result + subs = (n / 3) + 1; + } + return n - subs; +} +``` +We solve this problem in O(1) right now. So as we will be given **A** and **B** and we need to find how many numbers from these range are divisible by 3 we simply do this. +``` +long long result = numbers_divisible_by_3_from_1_to_n (B) - numbers_divisible_by_3_from_1_to_n (A - 1); +``` +So overall complexity of the solution is O(1). Super handy! + +### C++ +```cpp +#include +using namespace std; + +int testcase; +long long A, B; + +long long numbers_divisible_by_3_from_1_to_n (int n){ + if(n == 0) return 0; // Caution: we will also call numbers_divisible_by_3_from_1_to_n(A - 1). If A = 1 then the argument becomes -1 which can result in + // calculation. + int subs; + if(n % 3 == 0) { + subs = n / 3; + } else { // both n % 3 == 1 and n % 3 == 2 shows the same result + subs = (n / 3) + 1; + } + return n - subs; +} + +int main(){ + scanf("%d", &testcase); + for(int test = 1; test <= testcase; test++){ + scanf("%lld %lld", &A, &B); + long long result = numbers_divisible_by_3_from_1_to_n (B) - numbers_divisible_by_3_from_1_to_n (A - 1); + printf("Case %d: %lld\n", test, result); + } +} +``` + +Happy Coding! + +Written by: [Rahat Hossain](https://github.com/rahathossain690) diff --git a/1182/en.md b/1182/en.md new file mode 100644 index 00000000..f602f508 --- /dev/null +++ b/1182/en.md @@ -0,0 +1,139 @@ +# LOJ 1182 - Parity + +In this problem, you will be given `T` test cases. Each test case contains an integer `n`. Your task is to determine whether `n` has odd parity (odd number of set bits in its binary representation) or even parity (even number of set bits in its binary representation). Note: In a binary number, 0s are called `unset bits` and 1s are called `set bits`. + +One approach to solve this problem is to use the built-in function `__builtin_popcount` of `C++` or `bitCount` of `Java`. + +A second approach is to loop through all the bits of `n` and compute the total number of set bits. [This](https://www.hackerearth.com/practice/basic-programming/bit-manipulation/basics-of-bit-manipulation/tutorial/) and [this](https://www.topcoder.com/community/competitive-programming/tutorials/a-bit-of-fun-fun-with-bits/) will help you grasp the basics of bit manipulation for implementing this approach. + +A much better and optimized solution is in the use of **Brian Kernighan's Algorithm**. [Here](https://medium.com/@sanchit3b/brian-kernighans-algorithm-9e0ca5989148) is a tutorial to help you understand the algorithm. + +This is a good-first problem to get you started with bit manipulation. However, some people might find it difficult to get an `Accepted` verdict. The reason could be one of the following: + +1. Errors with bitwise operations +2. Failing to provide proper output format +3. Missing new line on each line + +If you are still stuck with this problem, check the codes below: + +### C++ +----- +**Approach #1** +```cpp +#include +using namespace std; + +int main() { + int cases, num; + cin >> cases; + for (int i = 1; i <= cases; i++) { + cin >> num; + cout << "Case " << i << ": " << (ones & 1 ? "odd" : "even") << "\n"; + } + return 0; +} +``` + +**Approach #2** +```cpp +#include +using namespace std; + +int main() { + int cases, num, ones; + cin >> cases; + for (int i = 1; i <= cases; i++) { + cin >> num; + ones = 0; + for (int j = 0; j <= 31; j++) { + if (num & (1 << j)) { + ones++; + } + } + cout << "Case " << i << ": " << (ones & 1 ? "odd" : "even") << "\n"; + } + return 0; +} +``` + +**Approach #3** +```cpp +#include +using namespace std; + +int main() { + int cases, num, ones; + cin >> cases; + for (int i = 1; i <= cases; i++) { + cin >> num; + ones = 0; + for (; num; num = num & (num - 1), ones++); + cout << "Case " << i << ": " << (ones & 1 ? "odd" : "even") << "\n"; + } + return 0; +} +``` + +### Java +----- +**Approach #1** +```java +package com.loj.volume; + +import java.util.Scanner; + +class Parity { + public static void main(String[] args) throws Exception { + Scanner input = new Scanner(System.in); + int cases = input.nextInt(), num; + for (int i = 1; i <= cases; i++) { + num = input.nextInt(); + System.out.println("Case " + i + ": " + ((Integer.bitCount(num) & 1) > 0 ? "odd" : "even")); + } + } +} +``` + +**Approach #2** +```java +package com.loj.volume; + +import java.util.Scanner; + +class Parity { + public static void main(String[] args) throws Exception { + Scanner input = new Scanner(System.in); + int cases = input.nextInt(), num, ones; + for (int i = 1; i <= cases; i++) { + num = input.nextInt(); + ones = 0; + for (int j = 0; j <= 31; j++) { + if ((num & (1 << j)) > 0) { + ones++; + } + } + System.out.println("Case " + i + ": " + ((ones & 1) > 0 ? "odd" : "even")); + } + } +} +``` + +**Approach #3** +```java +package com.loj.volume; + +import java.util.Scanner; + +class Parity { + public static void main(String[] args) throws Exception { + Scanner input = new Scanner(System.in); + int cases = input.nextInt(), num, ones; + for (int i = 1; i <= cases; i++) { + num = input.nextInt(); + ones = 0; + for (; num > 0; num = num & (num - 1), ones++); + System.out.println("Case " + i + ": " + ((ones & 1) > 0 ? "odd" : "even")); + } + } +} +``` diff --git a/1227/bn.md b/1227/bn.md new file mode 100644 index 00000000..b0345806 --- /dev/null +++ b/1227/bn.md @@ -0,0 +1,155 @@ +# LOJ 1227 - Boiled Eggs + +**[Problem](http://lightoj.com/volume_showproblem.php?problem=1227):** তোমাকে **n** সংখ্যক ডিম দেয়া হল। সর্বোচ্চ কতটি ডিম তুমি একসাথে নিয়ে সিদ্ধ করতে পারবে? তুমি **P** এর চেয়ে বেশি সংখ্যক ডিম নিতে পারবেনা এবং তোমার নেয়া ডিমগুলোর মোট ওজন **Q** গ্রামের চেয়ে বেশি হতে পারবেনা। + +_Time limit: 500 ms_ + +_ইনপুট শুরু হবে পূর্ণ সংখ্যা `T`(≤ 100) দিয়ে যা টেস্টকেসের সংখ্যা নির্দেশ করবে._ + +_প্রতিটা কেস শুরু হবে তিনটা পূর্ণসংখ্যা `n` (1 ≤ n ≤ 30), `P` (1 ≤ P ≤ 30) এবং `Q` (1 ≤ Q ≤ 30) দিয়ে। পরবর্তী লাইনে n সংখ্যক ধন্যাত্মক পূর্ণসংখ্যা(10 এর বড় নয়) ঊর্ধ্বক্রমে সাজানো থাকবে। এই সংখ্যাগুলো একেকটা ডিমের ওজন নির্দেশ করবে।_ + +**O(n^2) টাইমে সমাধানের পদ্ধতি:** আমরা প্রতিটি ডিমের ওজন একটি n সাইজের অ্যারেতে রাখতে পারি। এরপর দুইটি for loop এর সাহায্যে আমরা সকল সম্ভাব্য ফলাফল হিসাব করতে পারি। সকল সম্ভাব্য ফলাফল থেকে সর্বোচ্চটি আমাদেরকে প্রিন্ট করতে হবে। এই পদ্ধতিতে O(n^2) টাইম আর O(n) মেমোরি খরচ হবে। + +**O(n) টাইমে সমাধানের পদ্ধতি:** যেহেতু n সংখ্যক ডিমগুলোর ওজন ইনপুটেই ছোট থেকে বড় ক্রমে সাজানো থাকবে, সেহেতু এদের মান অ্যারের ভিতরে রেখে অ্যারেকে sort করার প্রয়োজন নেই। আমরা একটি sum variable নিয়ে এর মধ্যে একেকটা ডিমের ওজন যোগ করতে থাকব যতক্ষণ পর্যন্ত না sum এর মান **Q** এর চেয়ে বেশি হওয়ার উপক্রম হয়। আমরা একটি counter variable দিয়ে কতগুলো ডিম এ পর্যন্ত নেয়া হয়েছে তার হিসাব রাখব। counter variable এর মান যতক্ষণ না **P** এর বেশি হওয়ার উপক্রম হচ্ছে, ততক্ষণ আমরা এক করে বাড়াতে থাকব। সবশেষে আমরা counter variable এর মান প্রিন্ট করব। এই পদ্ধতিতে O(n) টাইম আর O(1) মেমোরি খরচ হবে। + + +### C++ +----- +**O(n^2) Solution** +```c++ +#include +using namespace std; + +int main(){ + int testcase; + cin>>testcase; + + for(int t = 1; t <= testcase; t++){ + int n, P, Q; + cin >> n >> P >> Q; + + int a[n]; + for(int i = 0; i < n; i++) cin >> a[i]; + + int mx = 0; + for(int i = 0; i < n; i++){ + + int counter = 0, sumOfWeight = 0; + for(int j = i; j < n; j++){ + if(counter + 1 <= P && sumOfWeight + a[j] <= Q) { // counter+1<=P নিশ্চিত করে মোট ডিমসংখ্যা যেন কখনো P এর চেয়ে বেশি না হয়। sumOfWeight+x<=Q নিশ্চিত করে ডিমের মোট ওজন যেন কখনো Q এর বেশি না হয়। + sumOfWeight += a[j]; // sumOfWeight variable এর মাধ্যমে আমরা ডিমের মোট ওজনের হিসাব রাখছি + counter++; // counter variable এর মাধ্যমে আমরা এ পর্যন্ত নেয়া মোট ডিমসংখ্যার হিসাব রাখছি + mx = max(mx, counter); // প্রতিবার mx এর চেয়ে counter এর মান বড় হয়ে গেলে সর্বোচ্চ মান mx এ রাখছি + } + else break; + } + + } + + cout << "Case " << t << ": " << mx << endl; + } +} +``` + +**O(n) Solution** +```c++ +#include +using namespace std; + +int main(){ + int testcase; + cin>>testcase; + + for(int t=1; t<=testcase; t++){ + int n, P, Q; + cin >> n>> P>> Q; + + int sumOfWeight= 0, counter=0; + for(int i = 1; i <= n; i++ ){ + int x; + cin >> x; + + if(counter + 1 <= P && sumOfWeight + x <= Q){ // counter+1<=P নিশ্চিত করে মোট ডিমসংখ্যা যেন কখনো P এর চেয়ে বেশি না হয়। sumOfWeight+x<=Q নিশ্চিত করে ডিমের মোট ওজন যেন কখনো Q এর বেশি না হয়। + sumOfWeight += x; // sumOfWeight variable এর মাধ্যমে আমরা ডিমের মোট ওজনের হিসাব রাখছি + counter++; // counter variable এর মাধ্যমে আমরা এ পর্যন্ত নেয়া মোট ডিমসংখ্যার হিসাব রাখছি + } + + } + cout << "Case " << t << ": " << counter << endl; + } +} +``` + +### Java +----- +**O(n^2) Solution** +```java +package com.loj.volume; + +import java.util.Scanner; + +class BoiledEggs { + public static void main(String[] args) throws Exception { + Scanner scanner = new Scanner(System.in); + int cases = scanner.nextInt(); + for (int caseno = 1; caseno <= cases; ++caseno) { + int n = scanner.nextInt(); + int P = scanner.nextInt(); + int Q = scanner.nextInt(); + + int[] a = new int[n]; + for(int i = 0; i < n; i++) a[i] = scanner.nextInt(); + + int mx = 0; + for(int i = 0; i < n; i++){ + int counter = 0, sumOfWeight = 0; + for(int j = i; j < n; j++){ + if(counter + 1 <= P && sumOfWeight + a[j] <= Q) { // counter+1<=P নিশ্চিত করে মোট ডিমসংখ্যা যেন কখনো P এর চেয়ে বেশি না হয়। sumOfWeight+x<=Q নিশ্চিত করে ডিমের মোট ওজন যেন কখনো Q এর বেশি না হয়। + sumOfWeight += a[j]; // sumOfWeight variable এর মাধ্যমে আমরা ডিমের মোট ওজনের হিসাব রাখছি + counter++; // counter variable এর মাধ্যমে আমরা এ পর্যন্ত নেয়া মোট ডিমসংখ্যার হিসাব রাখছি + mx = Math.max(mx, counter); // প্রতিবার mx এর চেয়ে counter এর মান বড় হয়ে গেলে সর্বোচ্চ মান mx এ রাখছি + } + else break; + } + } + + System.out.println("Case " + caseno + ": " + mx); + } + } +} +``` + +**O(n) Solution** +```java +package com.loj.volume; + +import java.util.Scanner; + +class BoiledEggs { + public static void main(String[] args) throws Exception { + Scanner scanner = new Scanner(System.in); + int cases = scanner.nextInt(); + for (int caseno = 1; caseno <= cases; ++caseno) { + int n = scanner.nextInt(); + int P = scanner.nextInt(); + int Q = scanner.nextInt(); + + int sumOfWeight= 0, counter=0; + for(int i = 1; i <= n; i++ ){ + int x = scanner.nextInt(); + + if(counter + 1 <= P && sumOfWeight + x <= Q){ // counter+1<=P নিশ্চিত করে মোট ডিমসংখ্যা যেন কখনো P এর চেয়ে বেশি না হয়। sumOfWeight+x<=Q নিশ্চিত করে ডিমের মোট ওজন যেন কখনো Q এর বেশি না হয়। + sumOfWeight += x; // sumOfWeight variable এর মাধ্যমে আমরা ডিমের মোট ওজনের হিসাব রাখছি। + counter++; // counter variable এর মাধ্যমে আমরা এ পর্যন্ত নেয়া মোট ডিমসংখ্যার হিসাব রাখছি। + } + + } + + System.out.println("Case " + caseno + ": " + counter); + } + } +} +``` +Happy Coding! + +Written by: [Md. Arfaqur Rahman](https://www.facebook.com/arfaqur.rahman.31/) diff --git a/1227/en.md b/1227/en.md new file mode 100644 index 00000000..e0568fcb --- /dev/null +++ b/1227/en.md @@ -0,0 +1,157 @@ +# LOJ 1227 - Boiled Eggs + +**[Problem](http://lightoj.com/volume_showproblem.php?problem=1227):** You are given **n** eggs. In one trial, you need to boil the maximum number of eggs. You cannot take more than **P** eggs and the total weight of the eggs cannot be more than **Q** gm. + +_Time limit: 500 ms_ + +_Input starts with an integer `T` (≤ 100), denoting the number of test cases._ + +_Each case starts with three integers `n` (1 ≤ n ≤ 30), `P` (1 ≤ P ≤ 30) and `Q` (1 ≤ Q ≤ 30). The next line contains n positive integers (not greater than 10) in non-descending order. These integers denote the weight of the eggs in gm._ + +**O(n^2) Approach:** We can store the weight of each egg in an array of size n and run two for loops to calculate all possible answers. Among them, we need to print the maximum one. This approach will take O(n) space and O(n^2) time. + +**O(n) Approach:** As in the input the weight of each egg will be given in non-decreasing order, there is no need to store their values in an array and sort them. We can use a sum variable and keep adding the weight of each egg to the sum variable until it exceeds **Q**. We need a counter variable to keep track of the number of eggs taken so far until it exceeds **P**. In the end, we need to print the value of the counter variable. This approach will take O(1) space and O(n) time. + + +### C++ +----- +**O(n^2) Solution** +```c++ +#include +using namespace std; + +int main(){ + int testcase; + cin>>testcase; + + for(int t = 1; t <= testcase; t++){ + int n, P, Q; + cin >> n >> P >> Q; + + int a[n]; + for(int i = 0; i < n; i++) cin >> a[i]; + + int mx = 0; + for(int i = 0; i < n; i++){ + + int counter = 0, sumOfWeight = 0; + for(int j = i; j < n; j++){ + if(counter + 1 <= P && sumOfWeight + a[j] <= Q) { // counter+1<=P ensures that number of eggs never exceeds P. sumOfWeight+x<=Q ensures that total weight of eggs never exceeds Q + sumOfWeight += a[j]; // With the sumOfWeight variable, we are keeping track of the total weight of the eggs + counter++; // counter variable keeps track of the number of eggs + mx = max(mx, counter); // storing the maximum value of counter in mx every time + } + else break; + } + + } + + cout << "Case " << t << ": " << mx << endl; + } +} +``` + +**O(n) Solution** +```c++ +#include +using namespace std; + +int main(){ + int testcase; + cin>>testcase; + + for(int t=1; t<=testcase; t++){ + int n, P, Q; + cin >> n>> P>> Q; + + int sumOfWeight= 0, counter=0; + for(int i = 1; i <= n; i++ ){ + int x; + cin >> x; + + if(counter + 1 <= P && sumOfWeight + x <= Q){ // counter+1<=P ensures that number of eggs never exceeds P. sumOfWeight+x<=Q ensures that total weight of eggs never exceeds Q + sumOfWeight += x; // With the sumOfWeight variable, we are keeping track of the total weight of the eggs + counter++; // counter variable keeps track of the number of eggs + } + + } + cout << "Case " << t << ": " << counter << endl; + } +} +``` + + +### Java +----- +**O(n^2) Solution** +```java +package com.loj.volume; + +import java.util.Scanner; + +class BoiledEggs { + public static void main(String[] args) throws Exception { + Scanner scanner = new Scanner(System.in); + int cases = scanner.nextInt(); + for (int caseno = 1; caseno <= cases; ++caseno) { + int n = scanner.nextInt(); + int P = scanner.nextInt(); + int Q = scanner.nextInt(); + + int[] a = new int[n]; + for(int i = 0; i < n; i++) a[i] = scanner.nextInt(); + + int mx = 0; + for(int i = 0; i < n; i++){ + int counter = 0, sumOfWeight = 0; + for(int j = i; j < n; j++){ + if(counter + 1 <= P && sumOfWeight + a[j] <= Q) { // counter+1<=P ensures that number of eggs never exceeds P. sumOfWeight+x<=Q ensures that total weight of eggs never exceeds Q + sumOfWeight += a[j]; // With the sumOfWeight variable, we are keeping track of the total weight of the eggs + counter++; // counter variable keeps track of the number of eggs + mx = Math.max(mx, counter); // storing the maximum value of counter in mx every time + } + else break; + } + } + + System.out.println("Case " + caseno + ": " + mx); + } + } +} +``` + +**O(n) Solution** +```java +package com.loj.volume; + +import java.util.Scanner; + +class BoiledEggs { + public static void main(String[] args) throws Exception { + Scanner scanner = new Scanner(System.in); + int cases = scanner.nextInt(); + for (int caseno = 1; caseno <= cases; ++caseno) { + int n = scanner.nextInt(); + int P = scanner.nextInt(); + int Q = scanner.nextInt(); + + int sumOfWeight= 0, counter=0; + for(int i = 1; i <= n; i++ ){ + int x = scanner.nextInt(); + + if(counter + 1 <= P && sumOfWeight + x <= Q){ // counter+1<=P ensures that number of eggs never exceeds P. sumOfWeight+x<=Q ensures that total weight of eggs never exceeds Q + sumOfWeight += x; // With the sumOfWeight variable, we are keeping track of the total weight of the eggs + counter++; // counter variable keeps track of the number of eggs + } + + } + + System.out.println("Case " + caseno + ": " + counter); + } + } +} +``` + +Happy Coding! + +Written by: [Md. Arfaqur Rahman](https://www.facebook.com/arfaqur.rahman.31/) diff --git a/1238/en.md b/1238/en.md new file mode 100644 index 00000000..ebfb7ffd --- /dev/null +++ b/1238/en.md @@ -0,0 +1,158 @@ +# LOJ 1238 - Power Puff Girls +**Problem Statement:**

In this problem, we have a 2D grid denoting the home city of the three power puff girls - Blossom, Bubbles and Buttercup. Each cell of the grid is either- +* '**.**' means an empty place +* '**a**' denotes the position of Blossom +* '**b**' denotes the position of Bubbles +* '**c**' denotes the position of Buttercup +* '**m**' denotes that there is a monster +* '**h**' denotes their home +* '**\#**' denotes a wall and the girls can't pass through it
+ +The three power puff girls move simultaneously from their initial position. And in each minute, from their current cells, they can move to any four adjacent cells (North, East, West, South) if the destination cell is neither a wall nor the cell contains a monster.
+ +Now, we have to find the **maximum** of the shortest distances from the initial position of each power puff girl to home. In other words, if the shortest distance from the initial postiion of each power puff girl to home is +da, db and dc respectively, then, we have to find the
max(da, db, dc).
+### Solution Idea 1: + +Suppose, the shortest distance from the initial postiion of each power puff girl to home is da, db and dc respectively . To calculate the shortest distance between two cell in a 2D grid, we can use **Breadth-first search**. So, to calculate da, db and dc, we have to run bfs three times from the initial position of each power puff girl separately. Each time we will start bfs from the initial position of a different power puff girl and find the shortest distance from that power puff girl to home. After calculating da, db and dc separately, the final answer will be max(da, db, dc).
+See the code below to understand better
+### C++ +``` c++ +#include +using namespace std; +#define endl '\n' +int dx[]={1,-1,0,0}; +int dy[]={0,0,1,-1}; +const int mxN=25; +char grid[mxN][mxN]; +int n,m; +bool valid(int r,int c) { + return (r>=0 and r=0 and c>q; + vector>used(n,vector(m)); + vector>dist(n,vector(m)); + q.push({sx,sy}); + used[sx][sy]=true; + dist[sx][sy]=0; + while(q.size()) { + auto cur=q.front(); + q.pop(); + int x=cur.first,y=cur.second; + for(int i=0;i<4;i++) { + int tx=x+dx[i]; + int ty=y+dy[i]; + if(!valid(tx,ty) or used[tx][ty]) continue; + dist[tx][ty]=dist[x][y]+1; + used[tx][ty]=true; + q.push({tx,ty}); + } + } + return dist[hx][hy]; +} +void solve() { + cin>>n>>m; + int hx,hy; //initial position of home + vector>pos; + for(int i=0;i>grid[i][j]; + if(grid[i][j]=='h') { + hx=i,hy=j; + } + if(ppg(grid[i][j])) { + pos.push_back({i,j}); + } + } + } + int da=bfs(pos[0].first,pos[0].second,hx,hy); + int db=bfs(pos[1].first,pos[1].second,hx,hy); + int dc=bfs(pos[2].first,pos[2].second,hx,hy); + int ans=max({da,db,dc}); + cout<>test_case; + for(int tc=1;tc<=test_case;tc++) { + cout<<"Case "< **Time Complexity: O(T\*n\*m)**
+> **Can you solve it in more convenient way?** + +*** +### Solution Idea 2: +Do we really need to run bfs three times? Actually, we can solve this problem using single bfs. Instead of finding the shortest distance from each power puff girl to home, we can find the shortest distance from **home** to each power puff girl using single bfs. This approach is much more efficient than the previous approach. Using this approach, we can also solve the problem where power puff girls are more than 3, within the same time complexity. +### C++ +``` c++ +#include +using namespace std; +#define endl '\n' +int dx[]={1,-1,0,0}; +int dy[]={0,0,1,-1}; +const int mxN=25; +char grid[mxN][mxN]; +int n,m; +bool valid(int r,int c) { + return (r>=0 and r=0 and c>n>>m; + int hx,hy; + for(int i=0;i>grid[i][j]; + if(grid[i][j]=='h') { + hx=i,hy=j; + } + } + } + queue>q; + vector>used(n,vector(m)); + vector>dist(n,vector(m)); + q.push({hx,hy}); + used[hx][hy]=true; + dist[hx][hy]=0; + while(q.size()) { + auto cur=q.front(); + q.pop(); + int x=cur.first,y=cur.second; + for(int i=0;i<4;i++) { + int tx=x+dx[i]; + int ty=y+dy[i]; + if(!valid(tx,ty) or used[tx][ty]) continue; + dist[tx][ty]=dist[x][y]+1; + used[tx][ty]=true; + q.push({tx,ty}); + } + } + int ans=0; + for(int i=0;i>test_case; + for(int tc=1;tc<=test_case;tc++) { + cout<<"Case "< **Time Complexity: O(T\*n\*m)** \ No newline at end of file