From d53e576ce928ea87020138830914b1c60a95df8a Mon Sep 17 00:00:00 2001 From: mohab Date: Wed, 8 Sep 2021 11:51:49 +0200 Subject: [PATCH 1/5] application hint to non divisble subset added --- Algorithms/Implementation/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Algorithms/Implementation/README.md diff --git a/Algorithms/Implementation/README.md b/Algorithms/Implementation/README.md new file mode 100644 index 0000000..b22f410 --- /dev/null +++ b/Algorithms/Implementation/README.md @@ -0,0 +1,14 @@ +# Non divisible subset + Algorithm basically boils down to cleverly applying modulo. We know that no 2 elements can be + divisible by k, which also means the mod(k) of no two numbers can sum to k. For example with + k = 10, we can't have two numbers where first_number%k = 1 and second_number%k = 9, since those + would sum to a multiple k. Thus we'll either take all of the numbers whose value mod k is 1, or + all of the numbers whose value mod k is 9, whichever is bigger. Don't forget that we can also + include one multiple of k itself (since we only require that the SUM of any two numbers isn't + divisible by k). + +## Application + Non divisible subset algorithm can be used to calculate the maximum length of anomaly of + elements if there sums doesn't fit together, for example in a logistic center, where + boxes can contain other boxes recursively, non divisible subset divide the anomaly + into different segments, and return the count for those that doesn't fit together. From 050aa5619764a94a3747efc2d9c585295594571a Mon Sep 17 00:00:00 2001 From: mohab Date: Wed, 8 Sep 2021 12:56:58 +0200 Subject: [PATCH 2/5] added extra long factorial problem --- .../Implementation/Extra_Long_Factorials.cpp | 39 +++++++++++++++++++ .../Implementation/Non-divisible Subset.cpp | 14 +++---- 2 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 Algorithms/Implementation/Extra_Long_Factorials.cpp diff --git a/Algorithms/Implementation/Extra_Long_Factorials.cpp b/Algorithms/Implementation/Extra_Long_Factorials.cpp new file mode 100644 index 0000000..f1c76c3 --- /dev/null +++ b/Algorithms/Implementation/Extra_Long_Factorials.cpp @@ -0,0 +1,39 @@ +/* + * complexity: 1/10*O(N^2) + * author: mohab metwally +*/ +#include +#include + +using namespace std; + +int main() { + int n; + cin >> n; + + vector bigint; + bigint.push_back(1); + + for (int i=2; i <=n; i++) { + //(1) calculate factorial + for (auto it=bigint.begin(); it!=bigint.end(); it++) { + *it *=i; + } + //(2) move overflowing numbers (>=10) to new integer + for (int d=0; d<=bigint.size(); d++) { + //(3) detect over flow + if (bigint[d]<10) continue; + + if (d==bigint.size()-1) bigint.push_back(0); + + //(4) add overflow to subsequent int + bigint[d+1] += bigint[d]/10; + //(5) keep reminder to the current int + bigint[d]%= 10; + } + } + for (auto it = bigint.rbegin(); it!=bigint.rend(); it++) { + cout << *it; + } + return 0; +} diff --git a/Algorithms/Implementation/Non-divisible Subset.cpp b/Algorithms/Implementation/Non-divisible Subset.cpp index 20f6636..de5c8d3 100644 --- a/Algorithms/Implementation/Non-divisible Subset.cpp +++ b/Algorithms/Implementation/Non-divisible Subset.cpp @@ -7,11 +7,11 @@ using namespace std; // Algorithm basically boils down to cleverly applying modulo. We know that no 2 elements can be -// divisible by k, which also means the mod(k) of no two numbers can sum to k. For example with -// k = 10, we can't have two numbers where first_number%k = 1 and second_number%k = 9, since those -// would sum to a multiple k. Thus we'll either take all of the numbers whose value mod k is 1, or +// divisible by k, which also means the mod(k) of no two numbers can sum to k. For example with +// k = 10, we can't have two numbers where first_number%k = 1 and second_number%k = 9, since those +// would sum to a multiple k. Thus we'll either take all of the numbers whose value mod k is 1, or // all of the numbers whose value mod k is 9, whichever is bigger. Don't forget that we can also -// include one multiple of k itself (since we only require that the SUM of any two numbers isn't +// include one multiple of k itself (since we only require that the SUM of any two numbers isn't // divisible by k). int main() { @@ -20,7 +20,7 @@ int main() { long long *modArr = new long long[k]; memset(modArr, 0, sizeof(modArr)); for(long long i = 0; i < n; i++) { - long long tmp; + long long tmp; cin>>tmp; modArr[tmp%k]++; } @@ -37,9 +37,9 @@ int main() { if(k%2 == 0 && i == k/2 && modArr[k/2] > 0) { result++; } else { - result += tmp; + result += tmp; } - + } cout< Date: Thu, 9 Sep 2021 11:12:26 +0200 Subject: [PATCH 3/5] added queen's attack II --- .../Implementation/Queens_attack_II.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Algorithms/Implementation/Queens_attack_II.cpp diff --git a/Algorithms/Implementation/Queens_attack_II.cpp b/Algorithms/Implementation/Queens_attack_II.cpp new file mode 100644 index 0000000..31288e3 --- /dev/null +++ b/Algorithms/Implementation/Queens_attack_II.cpp @@ -0,0 +1,43 @@ +#include + +using namespace std; + +int main(int argc, char **args) { + int n, k, r_q, c_q; + std::cin >> n >> k; + std::cin >> r_q >> c_q; + vector> obstacles(k); + for (int i=0; i > r >> c; + obstacles[i].push_back(r); + obstacles[i].push_back(c); + } + int r = n-c_q; + int l = c_q-1; + int u = n-r_q; + int d = r_q-1; + int ur = std::min(u, r); + int ul = std::min(u, l); + int ld = std::min(l, d); + int rd = std::min(r, d); + for (int i=0; i < k; i++) { + if (obstacles[i][0] == r_q) { + if (obstacles[i][1] > c_q) r = std::min(r, obstacles[i][1]-c_q-1); + else l = std::min(l, c_q-obstacles[i][1]-1); + } else if (obstacles[i][1] == c_q) { + if (obstacles[i][0] > r_q) u = std::min(u, obstacles[i][0]-r_q-1); + else d = std::min(d, r_q-obstacles[i][0]-1); + } else if (std::abs(obstacles[i][0] -r_q) == std::abs(obstacles[i][1] - c_q)) { + if (obstacles[i][1]>c_q) { + if (obstacles[i][0]>r_q) ur = std::min(ur, obstacles[i][1]-c_q-1); + else rd = std::min(rd, obstacles[i][1] - c_q -1); + } else { + if (obstacles[i][0]>r_q) ul = std::min(ul, c_q-obstacles[i][1]-1); + else ld = std::min(ld, c_q-obstacles[i][1]-1); + } + } + } + std::cout << r+l+u+d+ur+ul+ld+rd; + return 0; +} From 2518b225002aa8005dab52d5cdeb97e9b72c0ba7 Mon Sep 17 00:00:00 2001 From: mohab Date: Thu, 9 Sep 2021 13:03:00 +0200 Subject: [PATCH 4/5] 3d surface area solution --- Algorithms/Implementation/3D_Surface_Area.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Algorithms/Implementation/3D_Surface_Area.cpp diff --git a/Algorithms/Implementation/3D_Surface_Area.cpp b/Algorithms/Implementation/3D_Surface_Area.cpp new file mode 100644 index 0000000..b422314 --- /dev/null +++ b/Algorithms/Implementation/3D_Surface_Area.cpp @@ -0,0 +1,30 @@ +#include + +using namespace std; + +int main(int argc, char **args) { + int H, W; + cin >> H >> W; + int A[H+2][W+2]; + //pad the matrix with zero reference height + for (int i=0; i <= H+1; i++) { + for (int j=0; j<= W+1; j++) { + if (i==0 || j==0 || i>H || j>W) A[i][j] = 0; + else cin >> A[i][j]; + + } + } + int area=2*H*W; //upper and lower area, 100>=H,W>=1 + for (int i=1; i<=H; i++) { + for (int j=1; j <=W; j++) { + //sum the area along the height forward, and backward + area += std::max(0, A[i][j]-A[i][j-1]); + area += std::max(0, A[i][j]-A[i][j+1]); + //sum the area along the width forward, and backward + area += std::max(0, A[i][j]-A[i-1][j]); + area += std::max(0, A[i][j]-A[i+1][j]); + } + } + std::cout << area; + return 0; +} From 3dfad885bd7ec2ead8b761d34311e85d474ddfbb Mon Sep 17 00:00:00 2001 From: mohab Date: Tue, 14 Sep 2021 15:19:22 +0200 Subject: [PATCH 5/5] added larry's array implementation --- .../Implementation/Absolute Permutation.cpp | 218 +++++++++--------- Algorithms/Implementation/Larry's_Array.cpp | 40 ++++ 2 files changed, 149 insertions(+), 109 deletions(-) create mode 100644 Algorithms/Implementation/Larry's_Array.cpp diff --git a/Algorithms/Implementation/Absolute Permutation.cpp b/Algorithms/Implementation/Absolute Permutation.cpp index 12569a7..6c15ea4 100644 --- a/Algorithms/Implementation/Absolute Permutation.cpp +++ b/Algorithms/Implementation/Absolute Permutation.cpp @@ -7,118 +7,118 @@ using namespace std; // While this solution works, there is a much more elegant solution I found after reading the editorial. -// If N is even, then we simply need to consider N as a bunch 2*K slots. Solve the problem +// If N is even, then we simply need to consider N as a bunch 2*K slots. Solve the problem // for each "slot" instead of solving for N directly. int main() { - int T; - cin>>T; - while(T > 0) { - long long N, K; - cin>>N>>K; + int T; + cin>>T; + while(T > 0) { + long long N, K; + cin>>N>>K; - // Algorithm basically reduces down to either an edge case or an outside->inside approach - if(K == 0) { - for(long long i = 1; i <= N; i++) { - cout< N/2 || N%2 == 1) { - cout<<"-1\n"; - T--; - continue; - } + // Algorithm basically reduces down to either an edge case or an outside->inside approach + if(K == 0) { + for(long long i = 1; i <= N; i++) { + cout< N/2 || N%2 == 1) { + cout<<"-1\n"; + T--; + continue; + } - // *sigh* here we go... - bool possible = true; - bool *used = new bool[N+1]; - long long *answer = new long long[N]; - memset(used, false, sizeof(used)); - for(long long i = 1; i <= N/2; i++) { - // Solve left index - if(i+K <= N && i-K >= 1) { - if(!used[i+K] && !used[i-K]) { - used[i-K] = true; - answer[i-1] = i-K; - } else if(!used[i+K] && used[i-K]) { - used[i+K] = true; - answer[i-1] = i+K; - } else if(used[i+K] && !used[i-K]) { - used[i-K] = true; - answer[i-1] = i-K; - } else { - possible = false; - break; - } - } else if(i+K > N && i-K >= 1) { - if(!used[i-K]) { - used[i-K] = true; - answer[i-1] = i-K; - } else { - possible = false; - break; - } - } else if(i+K <= N && i-K <= 1) { - if(!used[i+K]) { - used[i+K] = true; - answer[i-1] = i+K; - } else { - possible = false; - break; - } - } else { - possible = false; - break; - } - // Solve right index - long long rightIndex = N-i+1; - if(rightIndex+K <= N && rightIndex-K >= 1) { - if(!used[rightIndex+K] && !used[rightIndex-K]) { - used[rightIndex+K] = true; - answer[rightIndex-1] = rightIndex+K; - } else if(!used[rightIndex+K] && used[rightIndex-K]) { - used[rightIndex+K] = true; - answer[rightIndex-1] = rightIndex+K; - } else if(used[rightIndex+K] && !used[rightIndex-K]) { - used[rightIndex-K] = true; - answer[rightIndex-1] = rightIndex-K; - } else { - possible = false; - break; - } - } else if(rightIndex+K > N && rightIndex-K >= 1) { - if(!used[rightIndex-K]) { - used[rightIndex-K] = true; - answer[rightIndex-1] = rightIndex-K; - } else { - possible = false; - break; - } - } else if(rightIndex+K <= N && rightIndex-K <= 1) { - if(!used[rightIndex+K]) { - used[rightIndex+K] = true; - answer[rightIndex-1] = rightIndex+K; - } else { - possible = false; - break; - } - } else { - possible = false; - break; - } - } - // I can start to see why some people may not want to do this for a living... - if(!possible) { - cout<<"-1"; - } else { - for(int i = 0; i < N; i++) { - cout<= 1) { + if(!used[i+K] && !used[i-K]) { + used[i-K] = true; + answer[i-1] = i-K; + } else if(!used[i+K] && used[i-K]) { + used[i+K] = true; + answer[i-1] = i+K; + } else if(used[i+K] && !used[i-K]) { + used[i-K] = true; + answer[i-1] = i-K; + } else { + possible = false; + break; + } + } else if(i+K > N && i-K >= 1) { + if(!used[i-K]) { + used[i-K] = true; + answer[i-1] = i-K; + } else { + possible = false; + break; + } + } else if(i+K <= N && i-K <= 1) { + if(!used[i+K]) { + used[i+K] = true; + answer[i-1] = i+K; + } else { + possible = false; + break; + } + } else { + possible = false; + break; + } + // Solve right index + long long rightIndex = N-i+1; + if(rightIndex+K <= N && rightIndex-K >= 1) { + if(!used[rightIndex+K] && !used[rightIndex-K]) { + used[rightIndex+K] = true; + answer[rightIndex-1] = rightIndex+K; + } else if(!used[rightIndex+K] && used[rightIndex-K]) { + used[rightIndex+K] = true; + answer[rightIndex-1] = rightIndex+K; + } else if(used[rightIndex+K] && !used[rightIndex-K]) { + used[rightIndex-K] = true; + answer[rightIndex-1] = rightIndex-K; + } else { + possible = false; + break; + } + } else if(rightIndex+K > N && rightIndex-K >= 1) { + if(!used[rightIndex-K]) { + used[rightIndex-K] = true; + answer[rightIndex-1] = rightIndex-K; + } else { + possible = false; + break; + } + } else if(rightIndex+K <= N && rightIndex-K <= 1) { + if(!used[rightIndex+K]) { + used[rightIndex+K] = true; + answer[rightIndex-1] = rightIndex+K; + } else { + possible = false; + break; + } + } else { + possible = false; + break; + } + } + // I can start to see why some people may not want to do this for a living... + if(!possible) { + cout<<"-1"; + } else { + for(int i = 0; i < N; i++) { + cout< +#include +#include +#include +#include +using namespace std; + +int main() { + + int t; + cin>>t; + for(int i=0;i>n; + vectorv(n); + for(int j=0;j>v[j]; + int swaps=0; + for(int i=0;iv[j+1]){ + swap(v[j],v[j+1]); + swaps++; + } + } + } + if(swaps%2==0) + cout<<"YES"<