# My code list - 110 - I2P2 ## *midterm 1* :::spoiler HW2 - Gey cool~~ <font color="#FD3004">AC</font> ```c= //HW2 - Gey cool~ #include <stdio.h> #define LL long long int LL n, q; LL sum[2000001]; LL calculate_sum(LL x, LL y) { if (x > y) return (sum[n] - sum[x - 1] + sum[y]); else return (sum[y] - sum[x - 1]); } int main(void) { while (scanf("%lld %lld", &n, &q) != EOF) { //calculate prefix sum LL temp1; memset(sum, 0, sizeof(LL) * 2000001); for (int i = 0; i < n; i++) { scanf("%lld", &temp1); // 從1開始加, 因為index從1開始 sum[i + 1] = temp1 + sum[i]; } LL temp2, temp3, tempsum; LL biggest = 0, left = 0, right = 0; for (int i = 0; i < q; i++) { scanf("%lld %lld", &temp2, &temp3); tempsum = calculate_sum(temp2, temp3); if (tempsum > biggest) { left = temp2; right = temp3; biggest = tempsum; } } printf("Max_range: (%lld,%lld); Value: %lld\n", left, right, biggest); } return 0; } ``` ::: :::spoiler HW2 - TA's Heartfelt <font color="#FD3004">AC</font> ```c= // HW2 - TA's Heartfelt // unsigned can be remove, but more clearly when added #include <stdio.h> int main(void) { float x; while (~scanf("%f", &x)) { unsigned int ans = *((unsigned int *)&x); for(int i = 31; i >= 0; i--){ printf("%d",( ans & (1 << i) )? 1 : 0); } printf("\n"); } return 0; } ``` ::: :::spoiler HW2 - after rain - (partial judge) <font color="#FD3004">AC</font> ```c= //HW2 - after rain //it is empty when id = 0 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _NODE { char color[10]; struct _NODE *next; } Node; void insert(Node** head, char* color, int dest) { Node *now = (*head), *tmp; //stop when reach the last element or the number we want for(int id = 0; now->next != NULL && id != dest; now = now->next, id++); tmp = (Node*)malloc(sizeof(Node)); strcpy(tmp->color, color); tmp->next = now->next; now->next = tmp; } void erase1(Node** head, int dest) { Node *now = (*head), *prev = NULL; for(int id = 0; now->next != NULL && id != dest; prev = now, now = now->next, id++); if(prev == NULL) return; prev->next = now->next; free(now); } void erase2(Node** head, char* color) { Node *now = (*head), *prev = NULL; while(now != NULL) { if(!strcmp(now->color, color)){ prev->next = now->next; free(now); now = prev; } prev = now; now = now->next; } } void reverse(Node **head, int dest1, int dest2) { Node *now = (*head), *l = NULL, *tmp = NULL; int id; for(id = 0; now->next != NULL && id != dest1; l = now, now = now->next, id++); while(now->next !=NULL && id < dest2){ tmp = now->next; now->next = tmp->next; tmp->next = l->next; l->next = tmp; id++; } } //////////////////////////////////////////////////////////////////////////////////// void show(Node **head) { Node *now = (*head)->next; while(now!=NULL) { printf("%s ", now->color); now = now->next; } puts(""); } int n; char buf[100]; int num1, num2; Node *head; int main() { head = (Node*)malloc(sizeof(Node)); // create an empty node memset(head->color,'\0',sizeof(head->color)); head->next = NULL; scanf("%d",&n); while(n--) { scanf("%s",buf); if(!strcmp(buf,"insert")) { scanf("%s%d",buf,&num1); insert(&head, buf, num1); // insert <color> <dest> } else if(!strcmp(buf,"erase1")) { scanf("%d",&num1); erase1(&head, num1); // erase1 <dest> } else if(!strcmp(buf,"erase2")) { scanf("%s",buf); erase2(&head, buf); // erase2 <color> } else if(!strcmp(buf,"reverse")) { scanf("%d%d",&num1,&num2); reverse(&head, num1, num2); // reverse <dest1> <dest2> } else if(!strcmp(buf,"show")) { show(&head); } } return 0; } ``` ::: :::spoiler HW3 - Operation on Sequence <font color="#FD3004">AC</font> ```c= //HW3 - Operation on Sequence #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Node { int num; struct _Node *l, *r; }Node; void insert(Node** head, int val1, int val2); void erase(Node** head, int val); void move(Node** head, int val); void show(Node** head); char oper[10]; int val1, val2, val; int listLen = 1; int main() { int x, n; scanf("%d", &x); Node *head = (Node*)malloc(sizeof(Node)); head->num = x; head->l = head; head->r = head; scanf("%d", &n); while(n--) { scanf("%s", oper); if(!strcmp("insert", oper)){ scanf("%d %d", &val1, &val2); insert(&head, val1, val2); }else if(!strcmp("erase", oper)){ scanf("%d", &val); erase(&head, val); }else if(!strcmp("move", oper)){ scanf("%d", &val); move(&head, val); }else if(!strcmp("show", oper)){ show(&head); } } return 0; } void insert(Node** head, int val1, int val2) { Node *now = *head; while(val2--) { Node *tmp = (Node*)malloc(sizeof(Node)); tmp->num = val1; tmp->r = now->r; now->r->l = tmp; now->r = tmp; tmp->l = now; listLen++; //printf("listLen = %d\n", listLen); } } void erase(Node** head, int val) { Node *now = *head; while(val--){ Node *tar = now->r; Node *tmp = tar->r; now->r = tmp; tmp->l = now; free(tar); listLen--; } } void move(Node** head, int val) { Node *now = *head; int acc; if(val > 0) acc = val % listLen; else if (val < 0) acc = -1 * ((-1 * val) % listLen); while(acc != 0){ if(acc > 0){ now = now->r; acc--; //printf("move right 1\n"); }else if(acc < 0){ now = now->l; acc++; //printf("move left 1\n"); } } *head = now; return; } void show(Node** head) { Node* tmp = (*head); Node* end = (*head); while(tmp != NULL){ printf("%d", tmp->num); tmp = tmp->r; if(tmp == end) { printf("\n"); break; } else printf(" "); } } ``` ::: :::spoiler HW3 - Uncle Huang choose Tutor(Easy version) <font color="#FD3004">AC</font> ```c= //HW3 - Uncle Huang choose Tutor(Easy version) #ifndef FUNC_H_INCLUDED #define FUNC_H_INCLUDED #include <stdio.h> #include <stdlib.h> typedef struct _Node{ int number; struct _Node* next; }Node; Node *createList(int n) { Node *now = NULL; for(int i = 1; i <= n; i++){ Node *tmp = (Node *)malloc(sizeof(Node)); tmp->next = tmp; tmp->number = i; if( now != NULL ){ tmp->next = now->next;//make sure point to head now->next = tmp;//point to next one } now = tmp; } now = now->next;//go back to the first element return now; } int solveJosephus(Node **head, int step) { int ct = 0; Node *now = *head; while(now->next != *head){ now = now->next; ct++; } ct++; //calculate there are how many elements now = now->next; int remain_step = 0; for(int i = ct; i > 1; i--){ remain_step = (step % i); //remain step is corresponded to the "current student number" if( remain_step == 0 ) remain_step += i; remain_step --; while(1){ if(remain_step == 0 && now->number != -1) break; if(now->number != -1) remain_step --; now = now->next; } now->number = -1; } //find which element is the remain's while(1){ if(now->number != -1) return now->number; now = now->next; } } void freeList(Node* head) { Node *now = head; int ct = 0; while(now->next != head){ now = now->next; ct++; } while(ct--) { Node *tmp = now->next; free(now); now = tmp; } } #endif ``` ::: :::spoiler HW3 - typing - (partial judge) <font color="#FD3004">AC</font> ```c= //HW3 - Typing #include<stdio.h> #include<stdlib.h> #include<string.h> #define next ptr_to_next_node #define prev ptr_to_prev_node #define ch character typedef struct _NODE { char character; struct _NODE *ptr_to_next_node; struct _NODE *ptr_to_prev_node; } Node; Node *head, *tail, *cursor; char buf[10]; int num; char intype; void insert(Node **cur, char c); void deletion(Node **cur); void backspace(Node **cur); void go_left(Node **cur, int t); void go_right(Node **cur, int t); void go_home(Node **cur); void go_end(Node **cur); void show(); int main() { int n; scanf("%d",&n); head = (Node*)malloc(sizeof(Node)); head->next = head->prev = head; cursor = tail = head; while(n--) { scanf("%s",buf); if(!strcmp(buf,"insert")) { getchar(); scanf("%c",&intype); insert(&cursor, intype); } else if(!strcmp(buf,"deletion")) { deletion(&cursor); } else if(!strcmp(buf,"backspace")) { backspace(&cursor); } else if(!strcmp(buf,"go_left")) { scanf("%d", &num); go_left(&cursor, num); } else if(!strcmp(buf,"go_right")) { scanf("%d", &num); go_right(&cursor, num); } else if(!strcmp(buf,"go_home")) { go_home(&cursor); } else if(!strcmp(buf,"go_end")) { go_end(&cursor); } else if(!strcmp(buf,"show")) { show(); } } return 0; } void insert(Node **cur, char c) { Node *np = (Node*)malloc(sizeof(Node)); np->ch = c; np->next = (*cur)->next; np->prev = (*cur); (*cur)->next->prev = np; (*cur)->next = np; if((*cur)->next->next == head) { tail = (*cur)->next; //head->prev = tail; } } void deletion(Node **cur) { if( *cur != tail ) { //delete tmp Node *tmp = (*cur)->next; (*cur)->next = tmp->next; tmp->next->prev = (*cur); //change tail if( tmp == tail){ tail = *cur; } } } void backspace(Node **cur) { if( *cur != head ) { (*cur)->next->prev = (*cur)->prev; (*cur)->prev->next = (*cur)->next; (*cur) = (*cur)->prev; } } void go_left(Node **cur, int t) { while(t--) { *cur = (*cur)->prev; } } void go_right(Node **cur, int t) { while(t--) { *cur = (*cur)->next; } } void go_home(Node **cur) { *cur = head; } void go_end(Node **cur) { *cur = tail; } void show() { if(head == NULL) { printf("\n"); return; } Node *now = head->ptr_to_next_node; while(now != head) { printf("%c ", now->character); now = now->ptr_to_next_node; } printf("\n"); } ``` ::: :::spoiler HW4 - Crazy give head <font color="#FD3004">AC</font> ```c= //HW4 - crazy give head //debug : prefix is "int"; remember "b - plen + 1" may be less than zero! #include <stdio.h> #include <stdlib.h> #include <string.h> char s[1010], p[1010]; int q, a, b; int slen, plen; int main() { while (scanf("%s %s", s, p) != EOF) { slen = strlen(s); plen = strlen(p); int prefix[1010] = {0}; int count = 0; for (int i = 0; i < slen - (plen - 1); i++) { if (strncmp(s + i, p, plen) == 0) { count++; } //prefix start at 1 for (int j = i + 1; j <= i + plen; j++) { prefix[j] = count; } } //start to calculate the range of the require scanf("%d", &q); int tmp = 0, answer = 0, r; while (q--) { scanf("%d %d", &a, &b); if (b - plen + 1 < 0) r = b; else r = b - plen + 1; tmp = prefix[r] - prefix[a - 1]; if (tmp > answer) answer = tmp; } printf("%d\n", answer); memset(prefix, 0, sizeof(int) * 1010); } return 0; } ``` ::: :::spoiler HW4 - Uncle Huang Points Tutor <font color="#FD3004">AC</font> ```c= //HW4 - Uncle Huang Points Tutor #include <stdio.h> #include <stdlib.h> #define LL long long int LL m; LL fpw(LL x, LL y); int main() { LL x, y; scanf("%lld %lld %lld", &x, &y, &m); x = x % m; LL ans = fpw(x, y); printf("%lld\n", ans); return 0; } LL fpw(LL x, LL y) { if (y == 0) return 1 % m; LL tmp = fpw(x, y / 2); if (y % 2 == 0) return tmp * tmp % m; else return (tmp * tmp % m) * x % m; //tmp * tmp need to mod one time(may be too big), then available to * x } ``` ::: :::spoiler HW4 - Restaurants in Hsinchu <font color="#FD3004">AC</font> ```c= //12241 - Restaurants in Hsinchu #include<stdio.h> #include<stdlib.h> #define LL long long int #define m 1000000007 LL n, ans; typedef struct{ LL aa, ab, ba, bb; }matrix22; typedef struct{ LL aa, ba; }matrix21; matrix22 tmp, identity, A; matrix21 final; void givenum() { A.aa = 1; A.ab = 1; A.ba = 1; A.bb = 0; identity.aa = 1; identity.ab = 0; identity.ba = 0; identity.bb = 1; } matrix22 mul(matrix22 x, matrix22 y) { matrix22 tmp; tmp.aa = ((x.aa * y.aa) + (x.ab * y.ba)) % m; tmp.ab = ((x.aa * y.ab) + (x.ab * y.bb)) % m; tmp.ba = ((x.ba * y.aa) + (x.bb * y.ba)) % m; tmp.bb = ((x.ba * y.ab) + (x.bb * y.bb)) % m; return tmp; } matrix21 mul2(matrix22 x) //因為F1 跟 F2 都是 1 //所以得到的矩陣跟 [1 // 1]相乘 { matrix21 tmp; tmp.aa = (x.aa + x.ab) % m; tmp.ba = (x.ba + x.bb) % m; return tmp; } matrix22 fpw(LL x) { if(x == 0) return identity; matrix22 tmp = fpw(x / 2); tmp = mul(tmp, tmp); if(x % 2 == 1) tmp = mul(tmp, A); return tmp; } int main(void) { givenum(); while( scanf("%lld", &n) != EOF ) { if(n == 1) ans = 1; else if(n == 2) ans = 1; else{ final = mul2( fpw(n - 2) ); ans = final.aa; } printf("%lld\n", ans); ans = 0; } return 0; } ``` ::: :::spoiler lab1 - Count 1s <font color="#FD3004">AC</font> ```c= //HW4 12678 count 1's #include<stdio.h> long int total = 0; long long int sum[1000010]={0}; void count(long long int); int main(void) { int a; long long int x, y; scanf("%d", &a); for ( int i = 1; i <= 1000000; i++){ count(i); if ( i == 1 ){ sum[i] = total; } else { sum[i] = sum[i-1] + total; } total = 0; } for ( int i = 0; i < a; i++ ){ scanf("%lld%lld", &x, &y); printf("%lld\n", (sum[y]-sum[x-1]) ); } return 0; } void count(long long int num) { if ( num == 0 ){ return; } else{ if( num%10 == 1 ){ total+=1; } count(num/10); } } ``` ::: :::spoiler HW5 - Construct tree by inorder and preorder - (partial judge) <font color="#FD3004">AC</font> ```c= //HW5 - Construct tree by inorder and preorder //be careful to reset the index of preorder #include <stdio.h> #include <stdlib.h> #include <string.h> #define right ptr_to_right_node #define left ptr_to_left_node int n; typedef struct _NODE { int number; struct _NODE *ptr_to_right_node; struct _NODE *ptr_to_left_node; } Node; int idxSearch(int *arr, int start, int end, int value) { int i; for(i = start; i <= end; i++){ if (arr[i] == value) return i; } return -1; } Node *newNode(int val) { Node *node = (Node*)malloc(sizeof(Node)); node->number = val; node->left = node->right = NULL; return node; } Node* buildTree(int* Inorder, int* Preorder, int inorder_start, int inorder_end) { static int preorder_idx = 0; // need to remember where we read preorder last time if ( inorder_start > inorder_end ) return NULL; Node *tree_node = newNode(Preorder[preorder_idx++]); if (preorder_idx == n) preorder_idx = 0; /*be careful to reset the index of preorder, because end with EOF, you will not just have onecase*/ if( inorder_start == inorder_end ) return tree_node; int inorder_idx = idxSearch(Inorder, inorder_start, inorder_end, tree_node->number); tree_node->left = buildTree(Inorder, Preorder, inorder_start, inorder_idx - 1); tree_node->right = buildTree(Inorder, Preorder, inorder_idx + 1, inorder_end); return tree_node; //往最下面的階層找完之後,慢慢往回連結往root的branch //這一行可以不寫,不過要寫==的時候 } void showPostorder(Node* root) { if (root != NULL) { showPostorder(root->left); showPostorder(root->right); printf("%d ", root->number); } } void freeTree(Node *root) { if (root != NULL){ freeTree(root->left); freeTree(root->right); free(root); } } int main(void) { int id = 1; while( ~scanf( "%d", &n ) ) { int inorder[100], preorder[100]; for( int i = 0; i < n; i++ ) scanf( "%d", &inorder[i] ); for( int i = 0; i < n; i++ ) scanf( "%d", &preorder[i] ); Node *root = buildTree( inorder, preorder, 0, n-1 ); printf( "testcase%d: ", id++ ); showPostorder( root ); printf( "\n" ); freeTree( root ); } return 0; } ``` ::: :::spoiler HW5 - Species of Knuckles <font color="#FD3004">AC</font> ```c= //HW5 - Species of Knuckles //字母的ACSIIcode轉int記得減掉開頭的字元 //注意scanf會讀到enter #include <stdio.h> long long int n; int main(void) { int str[26] = {0}; scanf("%lld", &n); int flag = 0; for (long long int i = 0; i < n; i++) { char c; scanf(" %c", &c); // !!!!!!!!!!要空一個不然會讀到"\n" int k = (int)(c - 'a'); //!!!!!注意要轉換 if (str[k] == 0) str[k]++; else { flag = 1; break; } } if (flag == 1 || n == 1) printf("I'm the god of Knuckles!\n"); else printf("Different makes perfect\n"); return 0; } ``` ::: :::spoiler HW6 - Storm Area 51 <font color="#FD3004">AC</font> ```c= //HW6 - Storm Area 51 //using of atoi //stop being stupid of 條件運算子!!!!!!!!!!! #include <stdio.h> #include <stdlib.h> #include <string.h> char tmpstring[110]; char preorder[110][4]; int id = 0; int x, y, z; typedef struct _NODE { struct _NODE *l, *r; // left and right child int type; // 0:operator, 1:value, 2:variable char ch; // operator or variable int val; // value } Node; void build_tree(Node **root); void show_inorder(Node *root); int cal(Node *root); int main() { fgets(tmpstring, 110, stdin); int j = 0; int currentNUM = 0; for(int i = 0; tmpstring[i] != '\0'; i++){ if (tmpstring[i] == ' '){ j++; currentNUM = 0; } else /*小心要加else不然空格會被存進去preorder裡面*/ preorder[j][currentNUM++] = tmpstring[i]; } Node *tree = (Node *)malloc(sizeof(Node)); build_tree(&tree); show_inorder(tree); printf("\n"); scanf("%d %d %d", &x, &y, &z); printf("%d\n", cal(tree)); return 0; } void build_tree (Node** root ){ (*root) = (Node*)malloc(sizeof(Node)); char expr[4]; strcpy(expr, preorder[id]); id++; if (*expr == '+' || *expr == '-' || *expr == '*' || *expr == '/'){ (*root)->type = 0; (*root)->ch = *expr; build_tree( &(*root)->l); build_tree( &(*root)->r); } else if (*expr == 'x' || *expr == 'y' || *expr == 'z'){ (*root)->type = 2; (*root)->ch = *expr; (*root)->l = (*root)->r =NULL; } else if (*expr >= '0' && *expr <= '9'){ (*root)->type = 1; (*root)->val = atoi(expr); (*root)->l = (*root)->r =NULL; } return ; } void show_inorder( Node*root) { if(root != NULL){ show_inorder(root->l); if(root->type == 0) printf("%c", root->ch); else if(root->type == 1) printf("%d", root->val); else if(root->type == 2) printf("%c", root->ch); show_inorder(root->r); } } int cal(Node *root) { if (root->type == 0){ if (root->ch == '+') return cal(root->l) + cal(root->r); if (root->ch == '-') return cal(root->l) - cal(root->r); if (root->ch == '*') return cal(root->l) * cal(root->r); if (root->ch == '/') return cal(root->l) / cal(root->r); } else if(root->type == 1){ return root->val; } else{ if (root->ch == 'x') return x; if (root->ch == 'y') return y; if (root->ch == 'z') return z; } } ``` ::: :::spoiler HW6 - Lucky Ghoul Dawn baby <font color="#FD3004">AC</font> ```c= //HW6 - Lucky Ghoul Dawn baby //use binary search //TA use binary tree #include <stdio.h> #include <stdlib.h> #include <string.h> int a[2000010]; int BS(int start, int end, int target); int main() { int n, q; while (scanf("%d %d", &n, &q) != EOF) { for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } int p; //the input of the index while (q--) { scanf("%d", &p); int index = BS(1, n, p); if (index == -1) printf("Break your bridge!\n"); else printf("%d\n", index); } memset(a, 0, sizeof(int) * (n + 1)); } return 0; } int BS(int start, int end, int target) { int mid = (start + end) / 2; if (target == a[mid]) return mid; if (end < start) return -1; else if (target < a[mid]) return BS(start, mid - 1, target); else if (target > a[mid]) return BS(mid + 1, end, target); } ``` ::: :::spoiler HW6 - Lucky Ghoul Dawn baby(another version) <font color="#FD3004">AC</font> ```c= #include <stdio.h> #include <string.h> #include <stdlib.h> int bridge[2000005]; int n, q; int BS(int target); int main() { while (scanf("%d%d", &n, &q) != EOF) { for (int i = 1; i <= n; i++) scanf("%d", &bridge[i]); while(q--) { int a; scanf("%d", &a); int index = BS(a); if (index == 0) printf("Break your bridge!\n"); else printf("%d\n", index); } memset(bridge, 0, sizeof(int) * (n + 1)); } return 0; } int BS(int target) { //printf("target = %d\n", target); int L = 1, R = n, ans = -1; while (L <= R) { int M = (L + R) / 2; //printf("L = %d//M = %d//R = %d\n", L, M, R); if (bridge[M] > target) { R = M - 1; } else if (bridge[M] == target) { ans = M; break; } else { L = M + 1; } } //printf("ans = %d\n", ans); if (ans != -1) return ans; else return 0; } ``` ::: :::spoiler HW6 - Heatstroke Bamboo Rats <font color="#FD3004">AC</font> ```c= //HW7 - Heatstroke Bamboo Rats //difficult on delete the Node on a binary tree #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_N 1000006 #define left left_child #define right right_child int n, q; int a[MAX_N]; typedef struct _NODE { int level; struct _NODE *left_child, *right_child; } Node; void build_tree(Node **now, int *arr, int l, int r); int query_heatstroke(Node *now, int x); void eat_rat(Node **root, int x); int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); Node *root = NULL; build_tree(&root, a, 0, n - 1); scanf("%d", &q); while (q--) { int x; scanf("%d", &x); if (query_heatstroke(root, x) != 0) { puts("We might as well eat it."); eat_rat(&root, x); } else puts("No dinner tonight."); } return 0; } void build_tree(Node **now, int *arr, int l, int r) { if (l > r) return; (*now) = (Node *)malloc(sizeof(Node)); if (l == r) // reach the bottom, plug in the value { (*now)->level = arr[l]; (*now)->left = (*now)->right = NULL; } else { int mid = (l + r) / 2; (*now)->level = arr[mid]; build_tree(&((*now)->left), arr, l, mid - 1); build_tree(&((*now)->right), arr, mid + 1, r); } } int query_heatstroke(Node *now, int x) { if (now == NULL) return 0; else if (now->level == x) return 1; else if (now->level > x) return query_heatstroke(now->left, x); else return query_heatstroke(now->right, x); } // seperate the delete node into : 0 child/ 1 child/ 2 children void eat_rat(Node **root, int x) { Node **cur = root; // set the current to our target x first while ((*cur)->level != x) { if ((*cur)->level > x) cur = &((*cur)->left); else cur = &((*cur)->right); } // if the target x has 0 child if ((*cur)->left == NULL && (*cur)->right == NULL) { (*cur) = NULL; } // if target x has 2 child // can choose pull up the smallest on right side // or choose pull up the biggest on left side else if ((*cur)->left != NULL && (*cur)->right != NULL) { Node *big = (*cur)->right; while (big->left != NULL) big = big->left; // find the smallest index int val = big->level; // val is the index to be pull up (*cur)->level = val; eat_rat(&((*cur)->right), val); // delete the old val position } // if target x has 1 child // just link them up else { if ((*cur)->left != NULL) (*cur) = (*cur)->left; else (*cur) = (*cur)->right; } } ``` ::: :::spoiler HW7 - Construct tree by inorder and postorder <font color="#FD3004">AC</font> ```c= //HW7 - Construct tree by inorder and postorder #include <stdio.h> #include <stdlib.h> #include <string.h> #define right ptr_to_right_node #define left ptr_to_left_node int n, post_now, inorder[100], postorder[100];; typedef struct _NODE { int number; struct _NODE *ptr_to_right_node; struct _NODE *ptr_to_left_node; } Node; int idxSearch(int start, int end, int value) { int i; for (i = start; i <= end; i++) { if (inorder[i] == value) return i; } return -1; } Node *newNode(int val) { Node *node = (Node *)malloc(sizeof(Node)); node->number = val; node->left = node->right = NULL; return node; } Node *buildTree(int inorder_start, int inorder_end) { if (inorder_start > inorder_end) //範圍不符合了 return NULL return NULL; Node *tree_node = newNode(postorder[post_now--]); //new完之後先把now改成下一個post的位置方便下一個迴圈用 if (inorder_start == inorder_end) return tree_node; //這一行可以不寫,不過可以少進兩次buildtree int inorder_idx = idxSearch(inorder_start, inorder_end, tree_node->number); //找post的值在inorder的那一個位置 tree_node->right = buildTree(inorder_idx + 1, inorder_end); //in+post建立tree要從tree->right開始建立 tree_node->left = buildTree(inorder_start, inorder_idx - 1); return tree_node; //往最下面的階層找完之後,慢慢往回連結往root的branch //這一行可以不寫,不過要寫==的時候 } void showPreorder(Node *root) { if (root != NULL) { printf("%d ", root->number); showPreorder(root->left); showPreorder(root->right); } } void freeTree(Node *root) { if (root != NULL) { freeTree(root->left); freeTree(root->right); free(root); } } int main(void) { int id = 1; while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) scanf("%d", &inorder[i]); for (int i = 0; i < n; i++) scanf("%d", &postorder[i]); //設定全域變數,從postorder的最後一個值開始建立樹 post_now = n - 1; Node *root = buildTree(0, n - 1); printf("testcase%d: ", id++); showPreorder(root); printf("\n"); freeTree(root); memset(inorder, 0, 100); memset(postorder, 0, 100); } return 0; } ``` ::: :::spoiler HW7 - Thanos' Dilemma <font color="#FD3004">AC</font> ```c= #include<stdio.h> #include<stdlib.h> #define LL long long int LL t, x, ans, m = 1000000007; //3*3matrix typedef struct{ LL aa, ab, ac; LL ba, bb, bc; LL ca, cb, cc; }matrix; //3*1matrix typedef struct{ LL aa, ba, ca; }matrix2; matrix A, All1; matrix2 final; void givenum() { A.aa = 1; A.ab = 2; A.ac = 1; A.ba = 1; A.bb = 0; A.bc = 0; A.ca = 0; A.cb = 1; A.cc = 0; All1.aa = 1; All1.ab = 0; All1.ac = 0; All1.ba = 0; All1.bb = 1; All1.bc = 0; All1.ca = 0; All1.cb = 0; All1.cc = 1; return; } matrix2 mulp(matrix x) { matrix2 tmp; tmp.aa = ((x.aa * 13) + (x.ab * 12) + (x.ac)) % m; tmp.ba = ((x.ba * 13) + (x.bb * 12) + (x.bc)) % m; tmp.ca = ((x.ca * 13) + (x.cb * 12) + (x.cc)) % m; return tmp; } matrix mul(matrix x, matrix y) { matrix z; z.aa = ((x.aa * y.aa) + (x.ab * y.ba) + (x.ac * y.ca)) % m; z.ab = ((x.aa * y.ab) + (x.ab * y.bb) + (x.ac * y.cb)) % m; z.ac = ((x.aa * y.ac) + (x.ab * y.bc) + (x.ac * y.cc)) % m; z.ba = ((x.ba * y.aa) + (x.bb * y.ba) + (x.bc * y.ca)) % m; z.bb = ((x.ba * y.ab) + (x.bb * y.bb) + (x.bc * y.cb)) % m; z.bc = ((x.ba * y.ac) + (x.bb * y.bc) + (x.bc * y.cc)) % m; z.ca = ((x.ca * y.aa) + (x.cb * y.ba) + (x.cc * y.ca)) % m; z.cb = ((x.ca * y.ab) + (x.cb * y.bb) + (x.cc * y.cb)) % m; z.cc = ((x.ca * y.ac) + (x.cb * y.bc) + (x.cc * y.cc)) % m; return z; } matrix fpw(LL y) { if (y == 0) return All1; matrix tmp = fpw(y/2); tmp = mul(tmp, tmp); if (y % 2 == 1) tmp = mul(tmp, A); return tmp; } int main(void) { givenum(); scanf("%lld", &t); while(t--) { ans = 0; x = 0; scanf("%lld", &x); if(x == 0) ans = 0; else if(x == 1) ans = 1; else if(x == 2) ans = 12; else if(x == 3) ans = 13; else { final = mulp( fpw(x - 3) ); ans = final.aa; } printf("%lld\n", ans); } return 0; } ``` ::: :::spoiler HW7 - Go Down Chicken <font color="#FD3004">AC</font> ```c= // HW7 - Go Down Chicken //小心快速冪次方爆掉了 //假如自己設定從1開始, 那助教設定的0~n要記得變1~n+1 #include <stdio.h> #include <stdlib.h> #include <string.h> #define LL long long int #define DIV 1000000007 typedef struct { int times; // games size int id; // input sequence LL way; // ways to slove the game } Node; Node game[1000010]; int n, q; LL fpow(int exp); int compare(const void *x, const void *y); LL BS(LL x); int main() { game[0].way = -1; // 避免qsort亂掉 while (~scanf("%d %d", &n, &q)) { for (int i = 1; i <= n; i++) { scanf("%d(/`A`)/ ~I__I", &game[i].times); game[i].id = i; if (game[i].times % 2 == 1) game[i].way = 0; else { game[i].way = fpow((game[i].times / 2)); } } qsort(game, n + 1, sizeof(Node), compare); while (q--) { LL x; scanf("%lld", &x); LL index = BS(x); if (index == -1) printf("Go Down Chicken 404\n"); else printf("%lld\n", index); } } return 0; } LL fpow(int exp) { if(exp == 0) return 1; LL tmp = fpow(exp / 2); tmp = tmp * tmp % DIV; if (exp % 2 == 1) tmp = tmp * 2 % DIV; return tmp; } int compare(const void *x, const void *y) { long long int *p; long long int *q; //先將x, y轉換成(Node*), 得到->way之後, 再把way所屬的int值轉成地址( 亦即 & ) p = &(((Node *)x)->way); q = &(((Node *)y)->way); return (*p - *q); } LL BS(LL x) { LL L = 1, R = n + 1, ans = 0; while(L < R){ LL M = (L + R) / 2; if (game[M].way >= x){ ans = M; R = M; } else L = M + 1; } if (game[ans].way == x) return game[ans].id; else return -1; } ``` ::: :::spoiler HW7 - too many treasures <font color="#FD3004">AC</font> ```c= //HW7 - too many treasures #include <stdio.h> #define LL long long int int main() { LL n, q; scanf("%lld %lld", &n, &q); LL a[n + 1]; a[0] = 0; LL tmp; for (LL i = 1; i <= n; i++) { scanf("%lld", &tmp); if (tmp > 0) a[i] = a[i - 1] + tmp; else a[i] = a[i - 1]; } LL l, r, m; while (q--) { scanf("%lld %lld %lld", &l, &r, &m); printf("%lld\n", a[l + m - 1] - a[l - 1]); } return 0; } ``` ::: ## *midterm2* :::spoiler HW8 - Heatstroke Bamboo Rats 2 <font color="#FD3004">AC</font> ```c= //HW8 - Heatstroke Bamboo Rats 2 //difficult on delete the Node on a binary tree #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_N 10004 #define left left_child #define right right_child int n, q; int a[MAX_N]; char tmp[100]; typedef struct _NODE { int level; struct _NODE *left_child, *right_child; } Node; void build_tree(Node **now, int *arr, int l, int r); int query_heatstroke(Node *now, int x); void eat_rat(Node **root, int x); void buy_rat(Node **root, int x); int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); Node *root = NULL; build_tree(&root, a, 0, n - 1); scanf("%d", &q); while (q--) { scanf("%s", tmp); if (strcmp("heatstroke", tmp) == 0) { int x; scanf("%d", &x); if (query_heatstroke(root, x) != 0) { puts("We might as well eat it."); eat_rat(&root, x); } else puts("No dinner tonight."); } else if (strcmp("buy", tmp) == 0) { int x; scanf("%d", &x); buy_rat(&root, x); } } return 0; } void build_tree(Node **now, int *arr, int l, int r) { if (l > r) return; (*now) = (Node *)malloc(sizeof(Node)); if (l == r) // reach the bottom, plug in the value { (*now)->level = arr[l]; (*now)->left = (*now)->right = NULL; } else { int mid = (l + r) / 2; (*now)->level = arr[mid]; build_tree(&((*now)->left), arr, l, mid - 1); build_tree(&((*now)->right), arr, mid + 1, r); } } int query_heatstroke(Node *now, int x) { if (now == NULL) return 0; else if (now->level == x) return 1; else if (now->level > x) return query_heatstroke(now->left, x); else return query_heatstroke(now->right, x); } // seperate the delete node into : 0 child/ 1 child/ 2 children void eat_rat(Node **root, int x) { Node **cur = root; // set the current to our target x first while ((*cur)->level != x) { if ((*cur)->level > x) cur = &((*cur)->left); else cur = &((*cur)->right); } // if the target x has 0 child if ((*cur)->left == NULL && (*cur)->right == NULL) { (*cur) = NULL; } // if target x has 2 child // can choose pull up the smallest on right side // or choose pull up the biggest on left side else if ((*cur)->left != NULL && (*cur)->right != NULL) { Node *big = (*cur)->right; while (big->left != NULL) big = big->left; // find the smallest index int val = big->level; // val is the index to be pull up (*cur)->level = val; eat_rat(&((*cur)->right), val); // delete the old val position } // if target x has 1 child // just link them up else { if ((*cur)->left != NULL) (*cur) = (*cur)->left; else (*cur) = (*cur)->right; } } void buy_rat(Node **root, int x) { Node **now = root; while (*now != NULL) { if ((*now)->level > x) now = &((*now)->left); else now = &((*now)->right); } // 利用雙指針的性質,直接建立Node,就不用透過parent (*now) = (Node *)malloc(sizeof(Node)); (*now)->level = x; (*now)->left = (*now)->right = NULL; } ``` ::: :::spoiler HW8 - Heatstroke Bamboo Rats 2 (submit type) <font color="#FD3004">AC</font> ```c= #define left left_child #define right right_child void build_tree(Node **now, int *arr, int l, int r) { if (l > r) return; (*now) = (Node *)malloc(sizeof(Node)); if (l == r) // reach the bottom, plug in the value { (*now)->level = arr[l]; (*now)->left = (*now)->right = NULL; } else { int mid = (l + r) / 2; (*now)->level = arr[mid]; build_tree(&((*now)->left), arr, l, mid - 1); build_tree(&((*now)->right), arr, mid + 1, r); } } int query_heatstroke(Node *now, int x) { if (now == NULL) return 0; else if (now->level == x) return 1; else if (now->level > x) return query_heatstroke(now->left, x); else return query_heatstroke(now->right, x); } // seperate the delete node into : 0 child/ 1 child/ 2 children void eat_rat(Node **root, int x) { Node **cur = root; // set the current to our target x first while ((*cur)->level != x) { if ((*cur)->level > x) cur = &((*cur)->left); else cur = &((*cur)->right); } // if the target x has 0 child if ((*cur)->left == NULL && (*cur)->right == NULL) { (*cur) = NULL; } // if target x has 2 child // can choose pull up the smallest on right side // or choose pull up the biggest on left side else if ((*cur)->left != NULL && (*cur)->right != NULL) { Node *big = (*cur)->right; while (big->left != NULL) big = big->left; // find the smallest index int val = big->level; // val is the index to be pull up (*cur)->level = val; eat_rat(&((*cur)->right), val); // delete the old val position } // if target x has 1 child // just link them up else { if ((*cur)->left != NULL) (*cur) = (*cur)->left; else (*cur) = (*cur)->right; } } void buy_rat(Node **root, int x) { Node **now = root; while (*now != NULL) { if ((*now)->level > x) now = &((*now)->left); else now = &((*now)->right); } // 利用雙指針的性質,直接建立Node,就不用透過parent (*now) = (Node *)malloc(sizeof(Node)); (*now)->level = x; (*now)->left = (*now)->right = NULL; } ``` ::: :::spoiler HW8 - Hulk's Trouble <font color="#FD3004">AC</font> ```c= // HW8 - Hulk's Trouble #include <stdio.h> #include <stdlib.h> #define LL long long int LL x[100010], upper_bound, lower_bound; int tmp; int compare(const void *x, const void *y); LL upperbound(LL *arr, int len, LL tar); LL lowerbound(LL *arr, int len, LL tar); int main() { int n, q; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%lld", &x[i]); } qsort(x, n, sizeof(x[0]), compare); scanf("%d", &q); while (q--) { scanf("%d", &tmp); upper_bound = upperbound(x, n, tmp); lower_bound = lowerbound(x, n, tmp); printf("%lld\n", upper_bound - lower_bound); } return 0; } int compare(const void *x, const void *y) { LL *p, *q; p = ((LL *)x); q = ((LL *)y); return *p - *q; } LL upperbound(LL *arr, int len, LL tar) { int L = 0, R = len, M; while (L < R) { M = (L + R) / 2; if (arr[M] > tar) R = M; else L = M + 1; } return R; } LL lowerbound(LL *arr, int len, LL tar) { int L = 0, R = len, M; while (L < R) { M = (L + R) / 2; if (arr[M] >= tar) R = M; else L = M + 1; } return R; } ``` ::: :::spoiler HW8 - minimum mean of rectangle sum <font color="#FD3004">AC</font> ```c= // HW8 - minimum mean of rectangle sum #include<stdio.h> #include<stdlib.h> #define LL long long int LL smallest, tmp; int main() { int n, m, elements; scanf("%d %d", &n, &m); elements = n * m; while(elements--){ scanf("%lld", &tmp); if (tmp < smallest) smallest = tmp; } printf("%lld\n", smallest); return 0; } ``` ::: :::spoiler HW9 - Break my heart <font color="#FD3004">AC</font> ```c= //HW9 - Break my heart #include <iostream> #include <set> using namespace std; int main() { string in; int n; set<int> myset; cin >> n; while (n--) { cin >> in; if (in == "insert") { int tmp; cin >> tmp; myset.insert(tmp); } else if (in == "print") { int i = 0; for (auto it = myset.begin(); it != myset.end(); it++, i++) { cout << *it; if (i + 1 == myset.size()) cout << "\n"; else cout << " "; } } else if (in == "min") { if (!myset.size()) ; else { auto it = myset.begin(); cout << *it << endl; } } else if (in == "range_erase") { int l, r; cin >> l >> r; myset.erase(myset.lower_bound(l), myset.upper_bound(r)); } else if (in == "sum") { int i = 0; for (auto it = myset.begin(); it != myset.end(); it++) { i += *it; } cout << i << endl; } } return 0; } ``` ::: :::spoiler HW9 - Thanos' Return_cpp <font color="#FD3004">AC</font> ```c= #include <iostream> #include "function.h" using namespace std; int r, c; long long times; char op; Matrix M, ans; Matrix fast_add(Matrix mat, long long t) { Matrix rtn(mat.getrow(), mat.getcol()); for(; t; t >>= 1) { if(t&1) rtn = rtn + mat; mat = mat + mat; } return rtn; } Matrix fast_mul(Matrix mat, long long t) { Matrix rtn(mat.getrow(), mat.getcol()); for(int i = 0; i < mat.getrow(); i++) rtn[i][i] = 1; for(; t; t >>= 1) { if(t&1) rtn = rtn * mat; mat = mat * mat; } return rtn; } int main() { cin >> r >> c >> times >> op; M = Matrix(r, c); for(int i=0, tmp;i<r;i++) for(int j=0;j<c;j++) { cin >> tmp; M[i][j] = tmp % MOD; } switch (op) { case '+': ans = fast_add(M, times); break; case '*': ans = fast_mul(M, times); break; } ans.print(); return 0; } ``` ::: :::spoiler HW9 - Thanos' Return_h <font color="#FD3004">AC</font> ```c= #include <iostream> #include <cstring> #include <iomanip> const int MAX_N = 102; const int MOD = 10007; class Matrix { public: Matrix() { row = col = 0; memset(mat, 0, sizeof(mat)); } // TODO Matrix(int r, int c); const int &getrow() { return row; } const int &getcol() { return col; } // TODO int *operator[](const int &x); const int *operator[](const int &x) const { return mat[x]; } // TODO Matrix operator+(const Matrix &x) const; // TODO: be aware that this function is declared with friend!!! friend Matrix operator*(const Matrix &x, const Matrix &y); void print() { for (int i = 0; i < row; i++) { if (i == 0) std::cout << "/"; else if (i == row - 1) std::cout << "\\"; else std::cout << "|"; for (int j = 0; j < col; j++) { std::cout << std::right << std::setw(8) << mat[i][j]; } if (i == 0) std::cout << " \\\n"; else if (i == row - 1) std::cout << " /\n"; else std::cout << " |\n"; } } private: int mat[MAX_N][MAX_N]; int row, col; }; ////// submit the below function /* const int MOD = 10007; */ Matrix::Matrix(int r, int c) { row = r; col = c; memset(mat, 0, sizeof(mat)); } int *Matrix::operator[](const int &x) { return mat[x]; } Matrix Matrix::operator+(const Matrix &x) const { Matrix res(row, col); for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) res[i][j] = ((mat[i][j] + x[i][j]) % MOD + MOD) % MOD; return res; } // Cus it is a friend function, doesn't below to the Class matrix // So we don't need to write Matrix:: Matrix operator*(const Matrix &x, const Matrix &y) { Matrix res(x.row, y.col); for (int i = 0; i < x.row; i++) for (int j = 0; j < y.col; j++) for (int k = 0; k < x.col; k++) { res[i][j] += ((x[i][k] * y[k][j]) % MOD + MOD) % MOD; res[i][j] = (res[i][j] % MOD + MOD) % MOD; } return res; } ``` ::: :::spoiler HW9 - cat-toast crisis <font color="#FD3004">AC</font> ```c= #include <stdio.h> int n, r; // for number of point and the distance int x[1010], y[1010], visited[1010]; // for point matrix and visited int single, team;// for the number of the result int distance(int A, int B); int dfs(int now, int parent); int main() { scanf("%d %d", &n, &r); for (int i = 0; i < n; i++) { scanf("%d %d", &x[i], &y[i]); } for (int i = 0; i < n; i++) { if (visited[i] == 0) { if (dfs(i, -1)) team++; else single++; } } printf("%d %d\n", single, team); return 0; } int dfs(int now, int parent) { int group = 0; visited[now] = 1; for (int i = 0; i < n; i++) { if (i == now) continue; else if (i == parent) continue; else if (visited[i] == 1) continue; else if (distance(now, i))// two points are in the distance of r { dfs(i, now); // do DFS group++; } } if (group != 0) return 1; else return 0; } int distance(int A, int B) { if ((x[A] - x[B]) * (x[A] - x[B]) + (y[A] - y[B]) * (y[A] - y[B]) <= r * r) return 1; else return 0; } ``` ::: :::spoiler BONUS - 1 - the answer to life, the universe, and everything <font color="#FD3004">AC</font> ```c= #include<stdio.h> #include<stdlib.h> #define LL long long int LL G[100]; LL F[100]; LL input; int main() { G[0] = 1; G[1] = 0; for(int i = 2; i < 89; i++){ G[i] = G[i - 1] + G[i - 2]; //printf("%lld\n", G[i]); } while (~scanf("%lld", &input)){ LL min = 1000000000000000010; LL tmp; if (input == 0 || input == 1) printf("0\n"); else { for(int i = 1; i < 88; i++){ if ((input - G[i]) % G[i + 1] == 0){ tmp = ( (input - G[i]) / G[i + 1] ); if (tmp < min) min = tmp; } } printf("%lld\n", min); } } return 0; } ``` ::: :::spoiler HW10 - Big enough_cpp <font color="#FD3004">AC</font> ```c= #include "12469.h" #include<iostream> #include<string> using namespace std; int main(){ BigInt a, b; while( cin >> a >> b ){ cout << (a+b) << '\n'; cout << (a-b) << '\n'; } return 0; } ``` ::: :::spoiler HW10 - Big enough_h <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> #include <string> using namespace std; #define MAX_N 1000 #define MAX_Bit 5 #define MAX 100000 class BigInt { public: long long operator[](int i) const { return m[i]; } long long &operator[](int i) { return m[i]; } BigInt() { l = 1, m[0] = 0; sign = 1; } friend istream &operator>>(istream &, BigInt &); friend ostream &operator<<(ostream &, BigInt); BigInt operator+(const BigInt &y); BigInt operator-(const BigInt &y); private: long long m[MAX_N]; int l; //長度 int sign; }; istream &operator>>(istream &in, BigInt &b) { string ch; in >> ch; if (ch[0] == '-') { b.sign = 0; ch = ch.substr(1); // to move away the '-' } else b.sign = 1; reverse(ch.begin(), ch.end()); int id = 0; for (int i = 0; i < ch.length(); i += MAX_Bit) { string sub = ch.substr(i, 5); reverse(sub.begin(), sub.end()); b.m[id++] = stoi(sub); // turn string to int // cout << "cin = " << b.m[id - 1] << endl; } b.l = id; return in; } ostream &operator<<(ostream &out, BigInt b) { if (!b.sign) cout << "-"; /*if (b.l == 0) { out << "0"; return out; }*/ cout << b.m[b.l - 1]; for (int i = b.l - 2; i >= 0; i--) { out.width(MAX_Bit); out.fill('0'); out << b[i]; } return out; } BigInt BigInt::operator+(const BigInt &y) { BigInt x(*this); int XSIGN = 1, YSIGN = 1; if (!x.sign) XSIGN = -1; if (!y.sign) YSIGN = -1; int i; long long h = 0; for (i = 0; i < x.l || i < y.l || h; i++) { if (i < x.l && i < y.l) h += x[i] * XSIGN + y[i] * YSIGN; else if (i < x.l) h += XSIGN * x[i]; else if (i < y.l) { h += YSIGN * y[i]; // cout << "YSIGN = " << YSIGN << "y[i] = " << y[i] << endl; // cout <<"your 88\n"; } x.m[i] = h % MAX; h /= MAX; //cout << "for loop minus x.m[i] = " << x.m[i] << endl; } x.l = i; // define x.sign if (x.m[x.l - 1] < 0) x.sign = 0; else x.sign = 1; // deal with the 進位 if (!x.sign && x.l > 1) { for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] > 0) { x.m[i] -= MAX; x.m[i + 1] += 1; } // cout << "x[i] = " << x[i] << endl; } } else if (x.sign && x.l > 1) { // cout << " i am positive"; for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] < 0) { // cout << "x.m[i] = " << x.m[i] << " MAX =" << MAX << endl; x.m[i] += MAX; x.m[i + 1] -= 1; } } } for (int i = 0; i < x.l; i++) { if (x.m[i] < 0) x.m[i] *= -1; // cout << "after turn posx[i] = " << x[i] << endl; } // deal with start number is 0 int tmpi = x.l; while (x.m[tmpi - 1] == 0) { x.l -= 1; tmpi--; } if (x.l == 1 && x.m[0] == 0) { x.sign = 1; } return x; } BigInt BigInt::operator-(const BigInt &y) { BigInt x(*this); int XSIGN = 1, YSIGN = 1; if (!x.sign) XSIGN = -1; if (!y.sign) YSIGN = -1; int i; long long h = 0; for (i = 0; i < x.l || i < y.l || h; i++) { if (i < x.l && i < y.l) h += x[i] * XSIGN - y[i] * YSIGN; else if (i < x.l) h += XSIGN * x[i]; else if (i < y.l) { h += 0 - YSIGN * y[i]; //cout << "YSIGN = " << YSIGN << "y[i] = " << y[i] << endl; //cout <<"your 88\n"; } x.m[i] = h % MAX; h /= MAX; //cout << "for loop minus x.m[i] = " << x.m[i] << endl; } x.l = i; // define x.sign if (x.m[x.l - 1] < 0) x.sign = 0; else x.sign = 1; // deal with the 進位 if (!x.sign && x.l > 1) { for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] > 0) { x.m[i] -= MAX; x.m[i + 1] += 1; } //cout << "x[i] = " << x[i] << endl; } } else if (x.sign && x.l > 1) { //cout << " i am positive"; for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] < 0) { //cout << "x.m[i] = " << x.m[i] << " MAX =" << MAX << endl; x.m[i] += MAX; x.m[i + 1] -= 1; } } } for (int i = 0; i < x.l; i++) { if (x.m[i] < 0) x.m[i] *= -1; //cout << "after turn posx[i] = " << x[i] << endl; } // deal with start number is 0 int tmpi = x.l; while (x.m[tmpi - 1] == 0) { x.l -= 1; tmpi--; } if (x.l == 1 && x.m[0] == 0) { x.sign = 1; } return x; } ``` ::: :::spoiler HW10 - Big enough(submit type) <font color="#FD3004">AC</font> ```c= /*#include <iostream> #include <algorithm> #include <string> using namespace std; */ #define MAX_N 1000 #define MAX_Bit 5 #define MAX 100000 istream &operator>>(istream &in, BigInt &b) { string ch; in >> ch; if (ch[0] == '-') { b.sign = 0; ch = ch.substr(1); // to move away the '-' } else b.sign = 1; reverse(ch.begin(), ch.end()); int id = 0; for (int i = 0; i < ch.length(); i += MAX_Bit) { string sub = ch.substr(i, 5); reverse(sub.begin(), sub.end()); b.m[id++] = stoi(sub); // turn string to int // cout << "cin = " << b.m[id - 1] << endl; } b.l = id; return in; } ostream &operator<<(ostream &out, BigInt b) { if (!b.sign) cout << "-"; /*if (b.l == 0) { out << "0"; return out; }*/ cout << b.m[b.l - 1]; for (int i = b.l - 2; i >= 0; i--) { out.width(MAX_Bit); out.fill('0'); out << b[i]; } return out; } BigInt BigInt::operator+(const BigInt &y) { BigInt x(*this); int XSIGN = 1, YSIGN = 1; if (!x.sign) XSIGN = -1; if (!y.sign) YSIGN = -1; int i; long long h = 0; for (i = 0; i < x.l || i < y.l || h; i++) { if (i < x.l && i < y.l) h += x[i] * XSIGN + y[i] * YSIGN; else if (i < x.l) h += XSIGN * x[i]; else if (i < y.l) { h += YSIGN * y[i]; // cout << "YSIGN = " << YSIGN << "y[i] = " << y[i] << endl; // cout <<"your 88\n"; } x.m[i] = h % MAX; h /= MAX; //cout << "for loop minus x.m[i] = " << x.m[i] << endl; } x.l = i; // define x.sign if (x.m[x.l - 1] < 0) x.sign = 0; else x.sign = 1; // deal with the 進位 if (!x.sign && x.l > 1) { for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] > 0) { x.m[i] -= MAX; x.m[i + 1] += 1; } // cout << "x[i] = " << x[i] << endl; } } else if (x.sign && x.l > 1) { // cout << " i am positive"; for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] < 0) { // cout << "x.m[i] = " << x.m[i] << " MAX =" << MAX << endl; x.m[i] += MAX; x.m[i + 1] -= 1; } } } for (int i = 0; i < x.l; i++) { if (x.m[i] < 0) x.m[i] *= -1; // cout << "after turn posx[i] = " << x[i] << endl; } // deal with start number is 0 int tmpi = x.l; while (x.m[tmpi - 1] == 0) { x.l -= 1; tmpi--; } if (x.l == 1 && x.m[0] == 0) { x.sign = 1; } return x; } BigInt BigInt::operator-(const BigInt &y) { BigInt x(*this); int XSIGN = 1, YSIGN = 1; if (!x.sign) XSIGN = -1; if (!y.sign) YSIGN = -1; int i; long long h = 0; for (i = 0; i < x.l || i < y.l || h; i++) { if (i < x.l && i < y.l) h += x[i] * XSIGN - y[i] * YSIGN; else if (i < x.l) h += XSIGN * x[i]; else if (i < y.l) { h += 0 - YSIGN * y[i]; //cout << "YSIGN = " << YSIGN << "y[i] = " << y[i] << endl; //cout <<"your 88\n"; } x.m[i] = h % MAX; h /= MAX; //cout << "for loop minus x.m[i] = " << x.m[i] << endl; } x.l = i; // define x.sign if (x.m[x.l - 1] < 0) x.sign = 0; else x.sign = 1; // deal with the 進位 if (!x.sign && x.l > 1) { for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] > 0) { x.m[i] -= MAX; x.m[i + 1] += 1; } //cout << "x[i] = " << x[i] << endl; } } else if (x.sign && x.l > 1) { //cout << " i am positive"; for (int i = 0; i <= x.l - 1 - 1; i++) { if (x.m[i] < 0) { //cout << "x.m[i] = " << x.m[i] << " MAX =" << MAX << endl; x.m[i] += MAX; x.m[i + 1] -= 1; } } } for (int i = 0; i < x.l; i++) { if (x.m[i] < 0) x.m[i] *= -1; //cout << "after turn posx[i] = " << x[i] << endl; } // deal with start number is 0 int tmpi = x.l; while (x.m[tmpi - 1] == 0) { x.l -= 1; tmpi--; } if (x.l == 1 && x.m[0] == 0) { x.sign = 1; } return x; } ``` ::: :::spoiler HW10 - A lot of sandwiches <font color="#FD3004">AC</font> ```c= #include <iostream> // abstract class class Food { public: enum class Type { IdiotSandwich, NormalSandwich }; friend std::ostream &operator<<(std::ostream &out, Food &d) { d.print(out); return out; } Type getType() { return type; } void setType(Type x) { type = x; } virtual ~Food() {} private: virtual void print(std::ostream &out) {} Type type; }; class IdiotSandwich : public Food { public: IdiotSandwich(int x) { setType(Type::IdiotSandwich); setINT(x); } void setINT(int x) { intelligence = x; } int getINT() { return intelligence; } private: // TODO void print(std::ostream &out); int intelligence; }; class NormalSandwich : public Food { public: NormalSandwich(std::string x) { setType(Type::NormalSandwich); setName(x); } void setName(std::string x) { name = x; } std::string getName() { return name; } private: // TODO void print(std::ostream &out); std::string name; }; class Dish { public: Dish() { food = nullptr; } // TODO ~Dish(); Food &getFood() { return (*food); } const Food &getFood() const { return (*food); } // TODO friend std::istream &operator>>(std::istream &in, Dish &d); Food *food; }; int n; Dish dish; int main() { std::cin >> n; while (n--) { std::cin >> dish; std::cout << dish.getFood() << std::endl; } return 0; } ////////submit below function//////// Dish::~Dish() { delete food; } void IdiotSandwich::print(std::ostream &out) { out << "An idiot sandwich with intelligence level " << IdiotSandwich::getINT() << " only."; } void NormalSandwich::print(std::ostream &out) { out << NormalSandwich::getName() << ". Masterpiece of sandwiches."; } std::istream &operator>>(std::istream &in, Dish &d) { std::string str; int t1; in >> str; if (d.food != nullptr) { delete d.food; d.food = nullptr; } if (str == "Ramsay") { in >> t1; d.food = new IdiotSandwich(t1); } else d.food = new NormalSandwich(str); return in; } ////////submit the above function//////// ``` ::: :::spoiler HW10 - Endgame <font color="#FD3004">AC</font> ```c= #include <iostream> #include <queue> #include <utility> using namespace std; typedef pair<int, int> PAIR; queue<PAIR> q; PAIR tmpdest, tmpdist; int n, m; int toBeDestroyed = 0; char map[1001][1001]; int toX[] = {1, -1, 0, 0}; int toY[] = {0, 0, 1, -1}; int bfs(); int main() { cin >> n >> m; for(int i = 0; i < n; i ++){ for (int j = 0; j < m; j++){ cin >> map[i][j]; if (map[i][j] == 'I'){ tmpdest.first = i; tmpdest.second = j; q.push (tmpdest); //cout << q.front().first << q.front().second << endl; tmpdist.first = 0; tmpdist.second = 0; q.push (tmpdist); //cout << q.back().first << q.back().second << endl; } if(map[i][j] == 'T'){ toBeDestroyed += 1; } } } //cout << "T = " << toBeDestroyed << endl; cout << bfs() << endl; return 0; } int bfs() { while(!q.empty()){ PAIR now = q.front(); //cout <<"now = ("<< now.first << " " << now.second << ")" << endl; q.pop(); int dist = q.front().first; // cout << "dist = " << dist << endl; q.pop(); ////////////////////////////////////////////////////// // if (map[now.first][now.second] == 'C') continue; // ////////////////////////////////////////////////////// // why we cannot add the above line ? // // we make (O+x, O+y) be 'C' below, // // then it will run the loop again // // but we want to do (O+x, O+y)'s four position // // so if we ignore the (O+x, O+y) with 'C' // // it will stop doing forever !!!!!! // ////////////////////////////////////////////////////// for(int i = 0; i < 4; i++){ if (now.first + toX[i] >= m || now.second + toY[i] >= n || now.first + toX[i] < 0 || now.second + toY[i] < 0) continue; else if(map[now.first + toX[i]][now.second + toY[i]] == 'C') continue; else if(map[now.first + toX[i]][now.second + toY[i]] == 'T'){ toBeDestroyed--; if (!toBeDestroyed) return dist + 1; } // we already use this position, so we define to 'C' to //easy to do the remaining step map[now.first + toX[i]][now.second + toY[i]] = 'C'; //pushing the new position and the distance tmpdest.first = now.first + toX[i]; tmpdest.second = now.second + toY[i]; q.push (tmpdest); tmpdist.first = dist + 1; tmpdist.second = 0; q.push (tmpdist); } } return -1; } ``` ::: :::spoiler HW11 - So beautiful <font color="#FD3004">AC</font> ```c= #include <iostream> #include <map> #include <vector> using namespace std; map< int, map< char, vector<string> > > bucket; pair<int, char> vowel(string str); int main () { int n; cin >> n; string lyric; pair <int, char> key; while (n--){ cin >> lyric; key = vowel(lyric); bucket[key.first][key.second].push_back(lyric); } int comp = 0, uncomp = 0, single = 0; for(auto i : bucket){ single = 0; for(auto j : i.second){ comp += j.second.size() / 2; single += j.second.size() % 2; } uncomp += single / 2; } int ANS = 0; if (comp >= uncomp){ ANS += uncomp; ANS += (comp - uncomp) / 2; } else ANS += comp; cout << ANS << endl; return 0; } pair<int, char> vowel(string str) { pair<int, char> ans; int vow = 0; for(auto &i : str){ if (i == 'a' || i == 'e' || i == 'i' || i == 'o' || i == 'u'){ vow++; ans.second = i; } } ans.first = vow; return ans; } ``` ::: :::spoiler HW11 - The power of vector <font color="#FD3004">AC</font> ```c= #include <iostream> #include <set> #include <vector> #include <string> using namespace std; vector<int> V; set<pair<int, int>> record; int NUMBER = 0; pair<int, int> last_record; int main () { int n; string input; int element; cin >> n; while(n--){ cin >> input; if (input == "push_back"){ cin >> element; V.push_back(element); /*last_record.first = element; last_record.second = ++NUMBER;*/ record.insert({element, NUMBER + 1}); NUMBER++; } else if(input == "pop_back" && !V.empty()){ record.erase({V[NUMBER - 1], NUMBER}); V.pop_back(); NUMBER--; } else if(input == "find"){ cin >> element; if ( element <= NUMBER ){ cout << V[element - 1] << endl; } } else if(input == "min" && !V.empty()){ cout << record.begin()->first << " " << record.begin()->second << endl; } else if(input == "max" && !V.empty()){ cout << record.rbegin()->first << " " << record.rbegin()->second << endl; } } return 0; } ``` ::: :::spoiler HW11 - Salary thief <font color="#FD3004">AC</font> ```c= #include <iostream> #include <string.h> using namespace std; #define MOD 1000000007 #define LL long long int int main () { int n, x; cin >> n; while(n--){ cin >> x; string str; cin >> str; int id = 0; for (id = 0; id < x, str.length() <= x; id++){ //we just have to calculate the actual element below X number, //after that we can just times the length to get the answer string right = str.substr(id + 1); for(int i = 0; i < str[id] - '0' - 1; i++){ str += right; } } LL len = str.length(); //carry on the "id" for(int i = id; i < x; i++){ LL times = (str[i] - '0' - 1) % MOD; LL length_to_times = (len - (i + 1)) % MOD; LL temp = ( times * length_to_times + MOD) % MOD; len = ((len % MOD + temp % MOD) + MOD) % MOD; // the plus MOD above is to avoid len < 0 } cout << len << endl; } return 0; } ``` ::: :::spoiler HW11 - Nyan Cat Crisis <font color="#FD3004">AC</font> ```c= #include <iostream> #include <cstring> #include <string> using namespace std; pair<int, int> N[500]; int visited[500]; int n, r, k; int groupsize = 0; int distance(int A, int B); void dfs(int now, int parent); int main() { int t; cin >>t; while(t--) { int big = 0, small = 0; cin >> n >> r >> k; for(int i = 0; i < n; i++){ cin >> N[i].first >> N[i].second; } for(int i = 0; i < n; i++){ if (!visited[i]){ groupsize = 1; dfs(i, -1); if (groupsize >= k){ big++; } else { small++; } } } cout << small << " " << big << endl; memset(visited, 0, sizeof(int) * 500); } return 0; } int distance(int A, int B) { if ((N[A].first - N[B].first) * (N[A].first - N[B].first) + (N[A].second - N[B].second) * (N[A].second - N[B].second) <= r * r) return 1; else return 0; } void dfs(int now, int parent) { visited[now] = 1; for(int i = 0; i < n; i++){ if (i == now || i == parent || visited[i]) continue; else if (distance(i, now)){ dfs(i, now); groupsize++; } } } ``` ::: :::spoiler BONUS - 2 - Fix the Bug <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> #include <cstring> using namespace std; long long int a[200005]; long long int rem[15][200005]; int countDigit(int x) { int res = 0; while (x != 0) { x /= 10; res++; } return res; } int BSleft(long long int *arr, int start, int end, int target) { int mid = (start + end) / 2; if (start == end - 1) { if (arr[start] == target) { return start; } else if (arr[end] == target) { return end; } else { return -1; } } if (target <= arr[mid]) { return BSleft(arr, start, mid, target); } else { return BSleft(arr, mid, end, target); } } int BSright(long long int *arr, int start, int end, int target) { int mid = (start + end) / 2; if (start == end - 1) { if (arr[end] == target) { return end; } else if (arr[start] == target) { return start; } else { return -1; } } if (target >= arr[mid]) { return BSright(arr, mid, end, target); } else { return BSright(arr, start, mid, target); } } int main() { long long int n, k; while (cin >> n >> k) { memset(a, 0, sizeof(a)); memset(rem, 0, sizeof(rem)); long long int res = 0; for (int i = 0; i < n; ++i) { cin >> a[i]; } if (n == 1) { cout << 0 << endl; continue; } for (long long int i = 0, mul = 1; i <= 10; ++i, mul *= 10) { for (long long int j = 0; j < n; ++j) { rem[i][j] = ((a[j] % k) * (mul % k)) % k; } sort(rem[i], rem[i] + n); } for (int i = 0; i < n; ++i) { int digitNum = countDigit(a[i]); int toFind = (k - a[i] % k) % k; int l = BSleft(rem[digitNum], 0, n - 1, toFind); int r = BSright(rem[digitNum], 0, n - 1, toFind); if (l != -1 && r != -1) { res += (r - l + 1); long long int temp = a[i]; for (long long int j = 0; j < digitNum; ++j) { temp *= 10; } if ((temp + a[i]) % k == 0) { res--; } } } cout << res << endl; } return 0; } ``` ::: ## *final* :::spoiler HW12 - People nowadays <font color="#FD3004">AC</font> ```c= #include <iostream> #include <utility> #include <set> using namespace std; set< pair<int, string> > person; int main() { int n; cin >> n; while(n--){ string input; cin >> input; string name; int age; if (input == "born"){ cin >> name >> age; person.insert({age, name}); } else if(input == "find"){ cin >> name >> age; if ( person.find({age, name}) != person.end()) cout << "YES\n"; else cout << "NO\n"; } else if (input == "kill"){ cin >> name >> age; person.erase( {age, name} ); } else if (input == "young"){ cout << person.begin()->second << " " << person.begin()->first << endl; } } /* for(auto it = person.begin(); it != person.end(); it++){ cout << "name" << " " << it->first << " " << "age" << " " << it->second <<endl; } */ return 0; } ``` ::: :::spoiler HW12 - Poorgrammer <font color="#FD3004">AC</font> ```c= #include <iostream> #define ll long long using namespace std; ll n, m; ll a[200010] = {0}; ll test_day(ll day) { ll code = 0; int penality = 1; // the first cup for every day has no penality for (int i = 0; i < day; i++){ code += a[i]; } for(int i = day; i < n; i++){ // if less than penality, the cup of coffee is useless if (a[i] > penality) code += (a[i] - penality); // after a cycle of "DAY", penality need to be added if( (i + 1) % day == 0) penality++; } return code; } int main() { int t; cin >> t; while (t--) { cin >> n >> m; for(int i = 0; i < n; i++){ cin >> a[i]; } // use binary search!!! //at least one day, the most is n day // set R = n + 1 to let M has chance to touch n ll L = 1, R = n + 1, ans = -1; while( L < R ){ ll M = (L + R) / 2; // either bigger or equal to m will be the answer if( test_day(M) >= m ) R = ans = M; else L = M + 1; } cout << ans << endl; } return 0; } ``` ::: :::spoiler HW12 - The night's watch <font color="#FD3004">AC</font> ```c= #include <iostream> #include <climits> using namespace std; #define LL long long LL a[5010] = {0}; LL MIN(LL x, LL y); LL MAX(LL x, LL y); int main() { int t; cin >> t; while(t--){ int n, m, k; LL ans = 0; cin >> n >> m >> k; for(int i = 0; i < n; i++){ cin >> a[i]; } if (m <= k) k = m - 1; // 命令i個人拿頭 for(int i = 0; i <= k; i++){ LL at_least = INT_MAX; // j代表有多少無法控制的人拿頭 for(int j = 0; j <= m - k - 1; j++){ // 內層max: 我們自己選當然選最大 // 外層min:不能控制的情況,我們找最小 at_least = MIN( at_least, MAX(a[i + j], a[i + j + ( n - m )]) ); } // 可以控制k個人,所以找最大 ans = MAX(at_least, ans); } cout << ans << endl; } return 0; } LL MIN(LL x, LL y) { return x < y ? x : y; } LL MAX(LL x, LL y) { return x > y ? x : y; } ``` ::: :::spoiler HW12 - Got flunked <font color="#FD3004">X</font> ```c= ``` ::: :::spoiler HW13 - Skate Shoes Sliding <font color="#FD3004">AC</font> ```c= #include <iostream> // 其實能走到的範圍就是 [-l, r],總共有 l + r + 1 = N + 1 種可能 int l = 0, r = 0; int main() { int N; std::cin >> N; while(N--){ char input; std::cin >> input; if (input == 'L') l++; else if (input == 'R') r++; } std::cout << l + r + 1 << std::endl; return 0; } ``` ::: :::spoiler HW13 - Guard The Wall <font color="#FD3004">AC</font> ```c= #include <iostream> #include <climits> //for INT_MAX #include <cstring> //for memset using namespace std; #define MAX(x, y) x > y ? x : y #define MIN(x, y) x < y ? x : y int n, q; pair<int, int> soldier[5010]; int section[5010]; int tmpsection[5010]; int prefix[5010]; int takeout (int first_soldier); int main() { int t; cin >> t; while(t--){ cin >> n >> q; for(int i = 1; i <= q; i++){ cin >> soldier[i].first >> soldier[i].second; for(int j = soldier[i].first; j <= soldier[i].second; j++){ section[j]++; } } int ans = 0; // 枚舉拿掉一個人後 for(int i = 1; i <= q; i++){ ans = MAX(ans, takeout(i)); } cout << ans << endl; memset(soldier, 0, sizeof(soldier)); memset(section, 0, sizeof(section)); memset(prefix, 0, sizeof(prefix)); } return 0; } int takeout (int first_soldier) { int guarded = 0, reduce = INT_MAX; for(int i = 1; i <= n; i++){ tmpsection[i] = section[i]; } // 將第一個拿掉的人有guard的區域都-1 for(int i = soldier[first_soldier].first; i <= soldier[first_soldier].second; i++){ tmpsection[i]--; } for(int i = 1; i <= n; i++){ if(tmpsection[i] > 0) guarded++; // 對於只有一個人guard的區域建前綴和 if(tmpsection[i] == 1) prefix[i] = prefix[i - 1] + 1; else prefix[i] = prefix[i - 1]; } // 枚舉再拿掉哪一個人會減少最少區域 for(int second_soldier = 1; second_soldier <= q && second_soldier != first_soldier; second_soldier++){ reduce = MIN(reduce, prefix[soldier[second_soldier].second] - prefix[soldier[second_soldier].first - 1]); } memset(tmpsection, 0, sizeof(tmpsection)); return guarded - reduce; } ``` ::: :::spoiler HW13 - I got a perfect body <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> //for sort #include <cstring> //for memset using namespace std; #define LL long long int n, p, k; int a[300010] = {0}; LL prefix[300010] = {0}; int main() { int t; cin >> t; while (t--) { int NOP = 0; cin >> n >> p >> k; for (int i = 1; i <= n; i++) { cin >> a[i]; } sort(a + 1, a + 1 + n); prefix[1] = a[1]; for (int i = 1; i <= n; i++) { // 買到第i個物品要付num[i] + sum[i-1] 元 if (i < k) prefix[i] = prefix[i - 1] + a[i]; // 但是如果是第 i >= k 個物品,就只要付num[i] + sum[i-k] 元 // prefix[0] = 0 else // it is better to start with i = 1, because if i start with 0, then the second // element is i = 1, then i - k will be less than zero for k = 2; // so we use the corresponding index will be better // or we can set another else if(i == k) to start with index zero prefix[i] = prefix[i - k] + a[i]; } for (int i = 1; i <= n; i++) { if (p >= prefix[i]) NOP = i; } cout << NOP << endl; memset(a, 0, sizeof(a)); memset(prefix, 0, sizeof(prefix)); } return 0; } ``` ::: :::spoiler BONUS - 3 - Motto Hayaku <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> #define ll long long using namespace std; ll n,x,a,b; ll idx, target; ll final_idx, final_m, final_i, final_target; ll m, tmp_m; ll tmp_ans = 0, final_ans = 0; ll not_zero = 0; ll x_num = 0; pair<ll,ll>fin[100005]; pair<ll,ll>num[100005]; pair<ll,ll>final_num[100005]; pair<ll,ll>prefix[100005]; pair<ll,ll>prefix2[100005]; bool cmp(pair<ll,ll>a, pair<ll,ll>b) { return a.first < b.first; } bool cmp2(pair<ll,ll>a, pair<ll,ll>b) { return a.second < b.second; } ll u_bound(ll val, ll l, ll r) { ll left = l, right = r; while(left < right) { ll mid = (left + right) / 2; if(prefix[mid].first > val) right = mid; else left = mid + 1; } return right - 1; } int main() { cin >> n >> x >> a >> b >> m; for(ll i=1; i<=n; i++) { cin >> num[i].first; final_num[i].first = num[i].first; num[i].second = final_num[i].second = i; } num[0].first = num[0].second = 0; prefix2[0].first = prefix2[0].second = 0; sort(num+1,num+n+1,cmp); sort(final_num+1,final_num+n+1,cmp); for(ll i=1; i<=n; i++) { if(i >= 1) prefix[i].first = (i - 1) * num[i].first - prefix2[i-1].first; prefix2[i].first= (prefix2[i-1].first + num[i].first); prefix[i].second = prefix2[i].second = num[i].second; } /*for(int i=1; i<=n; i++) cout << num[i].first << " "; cout << endl; for(int i=1; i<=n; i++) cout << prefix[i].first << " "; cout << endl; for(int i=1; i<=n; i++) cout << prefix2[i].first << " "; cout << endl;*/ tmp_m = m; idx = u_bound(tmp_m, 1, n+1); target = num[idx].first; tmp_m -= prefix[idx].first; target = min(x, target + (tmp_m / idx)); //cout << "tmp_m: " << tmp_m << " target: " << target << " idx: " << idx << endl; tmp_m %= idx; for(ll i=idx; i>=1; i--) { final_num[i].first = target; final_num[i].second = num[i].second; if(target < x) { if(tmp_m) { tmp_m--; final_num[i].first++; } } } for(ll i=idx+1; i<=n; i++) { final_num[i].first = num[i].first; final_num[i].second = num[i].second; } for(ll i=1; i<=n; i++) if(final_num[i].first == x) x_num++; final_ans = target * b + x_num * a; for(ll i=n; i>=1; i--) { m -= (x - num[i].first); if(m <= 0) break; tmp_m = m; idx = u_bound(tmp_m, 1, n+1); target = num[idx].first; tmp_m -= prefix[idx].first; target = min(x, target + (tmp_m / idx)); tmp_m %= idx; tmp_ans = b * target + (n - i + 1) * a; if(tmp_ans >= final_ans) { //cout << "m: " << m << " idx: " << idx << " target: " << target << " tmp_m: " << tmp_m << " tmp_ans: " << tmp_ans << endl; not_zero = 1; final_ans = tmp_ans; final_i = i; final_idx = idx; final_m = tmp_m; final_target = target; } } if(not_zero) { for(ll i = final_idx; i>=1; i--) { final_num[i].first = final_target; final_num[i].second = num[i].second; if(final_m) { final_m--; final_num[i].first++; } } for(ll i = final_idx+1; i<final_i; i++) { final_num[i].first = num[i].first; final_num[i].second = num[i].second; } for(ll i=final_i; i<=n; i++) { final_num[i].first = x; final_num[i].second = num[i].second; } } sort(final_num+1, final_num+n+1, cmp2); cout << final_ans << '\n'; for(ll i=1; i<=n; i++) cout << final_num[i].first << " "; return 0; } ``` ::: :::spoiler HW14 - Eat candies <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> using namespace std; int main() { int t; cin >> t; while(t--) { int candy[3]; for(int i = 0; i < 3; i++){ cin >> candy[i]; } sort(candy, candy + 3); if(candy[2] > candy[0] + candy[1]){ cout << candy[0] + candy[1] << endl; } else { cout << ( candy[0] + candy[1] + candy[2] ) / 2 << endl; } } return 0; } ``` ::: :::spoiler HW14 - knuckle's name <font color="#FD3004">AC</font> ```c= #include <iostream> #include <cstring> #include <string> using namespace std; bool edge[30][30]; bool visited[30]; // dfs function void dfs(int i); int main() { int t; cin >> t; while(t--) { int n; cin >> n; memset(edge, false, sizeof(edge)); memset(visited, false, sizeof(visited)); while(n--) { string str; cin >> str; for(int i = 0; i < str.length(); i++){ if(i == 0){ edge[str[i] - 'a'][str[i] - 'a'] = true; } else { edge[str[i] - 'a'][str[i - 1] - 'a'] = true; edge[str[i - 1] - 'a'][str[i] - 'a'] = true; } } } // declare in local, remember to reset the num int ans = 0; for(int i = 0; i < 26; i++){ if( !visited[i] && edge[i][i] ){ dfs(i); ans++; } } cout << ans << endl; } return 0; } void dfs(int i) { visited[i] = true; for(int j = 0; j < 26; j++){ if( !visited[j] && edge[i][j] ){ dfs(j); } } } ``` ::: :::spoiler HW14 - Unlimited Triangle Work <font color="#FD3004">AC</font> ```c= #include <iostream> #include <cstring> #include <string> using namespace std; #define ll long long int ll ans[100005]; ll pre[100005]; ll answer = 0; int main() { int t; cin >> t; while(t--) { ll A, B, C, D; cin >> A >> B >> C >> D; answer = 0; memset(ans, 0, sizeof(ans)); memset(pre, 0, sizeof(pre)); for(ll i = A; i <= B; i++){ // set the range of x + y ll L = i + B; ll R = i + C + 1; pre[L] += 1; pre[R] -= 1; } for(ll i = A + B; i <= B + C + 1; i++){ // do prefix of x + y pre[i + 1] += pre[i]; } for(ll i = A + B; i <= C + D; i++){ // do prefix of z pre[i + 1] += pre[i]; } for(ll i = C; i <= D; i++){ //get answer for every z ans[i] = pre[C + D] - pre[i]; } for(ll i = C; i <= D; i++){ //sum up the answer answer += ans[i]; } cout << answer << endl; } return 0; } ``` ::: :::spoiler QUIZ - 4 - Poorgrammer - ver2 <font color="#FD3004">AC</font> ```c= #include <iostream> #include <algorithm> #define ll long long using namespace std; ll n, m; ll a[200010] = {0}; bool cmp(int x, int y) { return x > y; } ll test_day(ll day) { ll code = 0; int penality = 1; // the first cup for every day has no penality for (int i = 0; i < day; i++){ code += a[i]; } for(int i = day; i < n; i++){ // if less than penality, the cup of coffee is useless if (a[i] > penality) code += (a[i] - penality); // after a cycle of "DAY", penality need to be added if( (i + 1) % day == 0) penality++; } return code; } int main() { int t; cin >> t; while (t--) { cin >> n >> m; for(int i = 0; i < n; i++){ cin >> a[i]; } // in version 2, the sequence of coffee isn't from big to small sort(a, a + n, cmp); // use binary search!!! //at least one day, the most is n day // set R = n + 1 to let M has chance to touch n ll L = 1, R = n + 1, ans = -1; while( L < R ){ ll M = (L + R) / 2; // bigger than m will be the answer if( test_day(M) > m ) R = ans = M; else L = M + 1; } cout << ans << endl; } return 0; } ``` ::: :::spoiler QUIZ - 4 - Guard The Wall - ver2 <font color="#FD3004">AC</font> ```c= #include <iostream> #include <climits> #include <cstring> using namespace std; #define MAX(x, y) (x) > (y) ? (x) : (y) #define MIN(x, y) (x) < (y) ? (x) : (y) int n, q; pair<int, int> soldier[305]; int section[305]; int tmpsection[305]; int prefix[305]; int takeout(int first, int second) { int guarded = 0, reduce = INT_MAX; for(int i = 1; i <= n; i++){ tmpsection[i] = section[i]; } for(int i = soldier[first].first; i <= soldier[first].second; i++){ tmpsection[i]--; } for(int i = soldier[second].first; i <=soldier[second].second; i++){ tmpsection[i]--; } for(int i = 1; i <= n; i++){ if (tmpsection[i] > 0) guarded++; if (tmpsection[i] == 1) prefix[i] = prefix[i - 1] + 1; else prefix[i] = prefix[i - 1]; } /* cout << "first" << " " << first << "second" << " " << second << endl; cout << "prefix : "; for(int i = 1; i <= n; i++){ cout << prefix[i] << " "; } cout << endl; */ for(int i = 1; i <= q && i != first && i != second; i ++){ reduce = MIN(reduce, prefix[soldier[i].second] - prefix[soldier[i].first - 1]); } memset(tmpsection, 0, sizeof(tmpsection)); memset(prefix, 0, sizeof(prefix)); return guarded - reduce; } int main() { int t; cin >> t; while(t--){ cin >> n >> q; for(int i = 1; i <= q; i++){ cin >> soldier[i].first >> soldier[i].second; for(int j = soldier[i].first; j <= soldier[i].second; j++){ section[j]++; } } int ans = 0; for(int i = 1; i < q; i++){ for(int j = i + 1; j <= q; j++){ //cout << "i = " << i << "j = " << j << endl;//////////// int tmp = takeout(i, j); ans = MAX(ans, tmp); } } cout << ans << endl; memset(section, 0, sizeof(section)); memset(prefix, 0, sizeof(prefix)); memset(soldier, 0, sizeof(soldier)); } return 0; } ``` ::: :::spoiler Unlimited Triangle Work - ver2 - ver2 <font color="#FD3004">AC</font> ```c= #include <iostream> #include <memory.h> #include <string> using namespace std; #define ll long long int ll ans[100005]; ll pre[100005]; ll answer = 0; int main() { int t; cin >> t; while(t--) { ll A, B, C, D; cin >> A >> B >> C >> D; answer = 0; memset(ans, 0, sizeof(ans)); memset(pre, 0, sizeof(pre)); for(ll i = A; i <= B; i++){ // set the range of x + y ll L = i + B; ll R = i + C + 1; pre[L] += 1; pre[R] -= 1; } for(ll i = 1; i <100005; i++){ // do prefix of x + y pre[i] += pre[i - 1]; } for(ll i = 1; i <100005; i++){ // do prefix of z pre[i] += pre[i - 1]; } for(ll i = C; i <= D; i++){ //get answer for every z if(i % 2 == 0) ans[i] = pre[(int)(1.5 * i) - 1] - pre[i]; else ans[i] = pre[(int)(1.5 * i)] - pre[i]; } for(ll i = C; i <= D; i++){ //sum up the answer answer += ans[i]; } cout << answer << endl; } return 0; } ``` :::