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; +} 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 + +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/Larry's_Array.cpp b/Algorithms/Implementation/Larry's_Array.cpp new file mode 100644 index 0000000..14e6e43 --- /dev/null +++ b/Algorithms/Implementation/Larry's_Array.cpp @@ -0,0 +1,40 @@ +/* + * 1) A rotation does not change the parity of the number of inversions. + * 2) If the array is sortable, then the initial number of inversions is even. + * 3) If the initial number of inversions is even, then the array is sortable. +*/ + +#include +#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"<>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< + +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; +} 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.