pinterest.com
2655 字
13 分钟
让算法落地:「编程思维与实践」课程笔记
数据范围
数据类型 | 范围(2^x^) | 最大范围(10^x^) | 格式化控制符 |
---|---|---|---|
unsigned int | [0,2^32^-1] | 10^9^ | %u |
int | [-2^31^,2^31^-1] | 10^9^ | %d |
long long | [-2^63^,2^63^-1] | 10^18^ | %lld |
unsigned long long | [0,2^64^-1] | 10^19^ | %llu |
ASCII码
Dec | Char | Dec | Char | Dec | Char | Dec | Char | Dec | Char | Dec | Char |
---|---|---|---|---|---|---|---|---|---|---|---|
32 | 48 | 0 | 64 | @ | 80 | P | **96 ** | ` | 112 | p | |
33 | ! | 49 | 1 | 65 | A | 81 | Q | **97 ** | a | 113 | q |
34 | ” | 50 | 2 | 66 | B | 82 | R | **98 ** | b | 114 | r |
35 | # | 51 | 3 | 67 | C | 83 | S | **99 ** | c | 115 | s |
36 | $ | 52 | 4 | 68 | D | 84 | T | 100 | d | 116 | t |
37 | % | 53 | 5 | 69 | E | 85 | U | 101 | e | 117 | u |
38 | & | 54 | 6 | 70 | F | 86 | V | 102 | f | 118 | v |
39 | ’ | 55 | 7 | 71 | G | 87 | W | 103 | g | 119 | w |
40 | ( | 56 | 8 | 72 | H | 88 | X | 104 | h | 120 | x |
41 | ) | 57 | 9 | 73 | I | 89 | Y | 105 | i | 121 | y |
42 | * | 58 | : | 74 | J | 90 | Z | 106 | j | 122 | z |
43 | + | 59 | ; | 75 | K | 91 | [ | 107 | k | 123 | { |
44 | , | 60 | < | 76 | L | 92 | \ | 108 | l | 124 | | |
45 | - | 61 | = | 77 | M | 93 | ] | 109 | m | 125 | } |
46 | . | 62 | > | 78 | N | 94 | ^ | 110 | n | 126 | ~ |
47 | / | 63 | ? | 79 | O | 95 | _ | 111 | o |
数组传参
void f(char s[10]); // f(char *s)int main() { char s[10] = "LeeHero"; f(s); return 0;}
void f(char s[][10]); // f(char (*s)[10])int main() { char s[5][10] = {"Lee","Hero"}; f(s); return 0;}
代码模板
GCD/LCM
int gcd(int a, int b) { return b>0?gcd(b,a%b):a; }int lcm(int a, int b) { return a/gcd(a,b)*b; }
排序
一般模板
int cmp(const void *a, const void *b) { int x1 = *(int *)a; int x2 = *(int *)b; return x1-x2;}
int main() { int arr[] = {10, 5, 15, 12, 90, 80}; int n = sizeof(arr) / sizeof(arr[0]), i; qsort(arr, n, sizeof(int), cmp); // <- QSORT for (i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); return 0;}
结构体排序
typedef struct { char usr[20]; char dom[20];} EMAIL;
int cmp(const void *a, const void *b) { EMAIL *A = (EMAIL *)a; EMAIL *B = (EMAIL *)b; if (strcmp(A -> dom, B -> dom) == 0) { return strcmp(B -> usr, A -> usr); } else { return strcmp(A -> dom, B -> dom); }}
int main() { EMAIL *data = 0; int T; scanf("%d", &T); EMAIL *data = (EMAIL *)malloc(sizeof(EMAIL)*(T+10)); for (int i = 0; i < T; i++) { char ads[50] = {0}; scanf("%s", &ads); strcpy((data+i) -> usr, GetUsr(ads)); strcpy((data+i) -> dom, GetDom(ads)); } qsort(data, T, sizeof(EMAIL), cmp); // <- QSORT for (int i = 0; i < T; i++) printf("%s@%s\n", data[i].usr, data[i].dom); return 0;}
二维定长数组排序
int cmp(const void *a, const void *b) { char *n1 = (char *)a; char *n2 = (char *)b; return myStrCmp(n1, n2);}
int main() { char c; int i = 0; char words[120][100] = {0}; scanf("%s", words[i++]); while ((c = getchar()) != '\n') { scanf("%s", words[i++]); } qsort(words, i, sizeof(words[0]), cmp); // <- QSORT for (int j = 0; j < i; j++) printf("%s ", words[j]); printf("\n"); return 0;}
二维动态数组排序
int cmp(const void *a, const void *b) { int *n1 = *((int **)a); int *n2 = *((int **)b); return *(n1+1) - *(n2+1); //cmp car[x][1] & car[y][1]} //belike ((int *)a)[1]-((int *)b)[1]
int main() { int n, t; scanf("%d %d",&n,&t); int **car = (int **)malloc(n*sizeof(int*)); for (int i = 0; i < n; i++) { int *p = (int *)malloc(3*sizeof(int)); *(car+i) = p; } qsort(car, n, sizeof(car[0]), cmp); // <- QSORT return 0;}
int cmp(const void *a, const void *b) { char *p1 = *((char **)a); char *p2 = *((char **)b); //通过 *(p1+i) *(p2+i) 操作就可以解析到[一级指针所指字符串]的每个字符 //从而做进一步的比较处理 /* 后续省略 */ return ret;}
int main() { int N; scanf("%d", &N); char **email; email = (char **)malloc(N * sizeof(char*)); //char *email[N] for (int i = 0; i < N; i++) { scanf("%s", s); LEN = strlen(s); p = (char *)malloc((LEN+1) * sizeof(char)); strcpy(p, s); *(email + i) = p; } qsort(email, N, sizeof(email[0]), cmp); // <- QSORT for (int i = 0; i < n; i++) printf("%s\n",*(email+i)); return 0;}
大整数
#include <stdio.h>#include <string.h>
typedef struct { int cnt, v[1000]; //个位在前存储} BIGINT;
BIGINT int2BIG(int x) { //int转BIGINT BIGINT r = {0, {0}}; while (x > 0) { r.v[r.cnt++] = x % 10; x /= 10; } return r;}
BIGINT char2BIG(char *s) { BIGINT R = {0, {0}}; int len = strlen(s); int i; R.cnt = len; for (i = len - 1; i >= 0; i--) { R.v[len - 1 - i] = s[i] - '0'; } return R;}
void printBIG(BIGINT a) { if (a.cnt == 0) { printf("0\n"); return; } int len = a.cnt, i; while (a.v[len - 1] == 0) len--; for (i = len - 1; i >= 0; i--) printf("%d", a.v[i]); printf("\n");}
BIGINT mul(BIGINT S, BIGINT T) { //两个大整数相乘 if (S.cnt == 0 || T.cnt == 0) return int2BIG(0); BIGINT R = {S.cnt + T.cnt, {0}}; for (int i = 0; i < T.cnt; i++) { int t, k, j; int carry = 0; for (j = 0; j < S.cnt; j++) { t = S.v[j] * T.v[i] + carry + R.v[i + j]; R.v[i + j] = t % 10; carry = t / 10; } k = i + j; while (carry > 0) { t = carry + R.v[k]; R.v[k] = t % 10; carry = t / 10; k++; } } if (R.v[S.cnt + T.cnt - 1] == 0) R.cnt--; //最高位0不统计在一个大整数的位数中 return R;}
BIGINT add(BIGINT S, BIGINT T) { //两个大整数相加 BIGINT R = {0, {0}}; int i, carry = 0; for (i = 0; i < S.cnt && i < T.cnt; i++) { int temp = (S.v[i] + T.v[i] + carry); R.v[i] = temp % 10; carry = temp / 10; } while (i < S.cnt) { int temp = S.v[i] + carry; R.v[i++] = temp % 10; carry = temp / 10; } while (i < T.cnt) { int temp = T.v[i] + carry; R.v[i++] = temp % 10; carry = temp / 10; } if (carry) { R.v[i++] = carry % 10; } R.cnt = i; return R;}
int cmp(BIGINT S, BIGINT T) { //两个大整数的比较 int n = (S.cnt > T.cnt) ? S.cnt : T.cnt; for (int i = n - 1; i >= 0; i--) if (*(S.v + i) > *(T.v + i)) return 1; else if (*(S.v + i) < * (T.v + i)) return -1; return 0;}
void SUB(BIGINT *S, BIGINT *T, BIGINT *result) { //大数减小数 int n = (S->cnt > T->cnt) ? S->cnt : T->cnt; result->cnt = n; int carry = 0, i; for (i = 0; i < n; i++) { if ((*(S->v + i) + carry) < (*(T->v + i))) { *(result->v + i) = 10 + *(S->v + i) + carry - *(T->v + i); carry = -1; } else { *(result->v + i) = *(S->v + i) + carry - *(T->v + i); carry = 0; } } for (int i = n - 1; i >= 0 && !result->v[i]; i--) result->cnt--;}
BIGINT BIGSUB(BIGINT S, BIGINT T, int *sign) { BIGINT R = {0, {0}}; *sign = 1; if (cmp(S, T) >= 0) { *sign = 1; SUB(&S, &T, &R); } else { *sign = -1; SUB(&T, &S, &R); } return R;}
int main() { char s1[600], s2[600]; BIGINT a = {0, {0}}, b = {0, {0}}, c = {0, {0}}; int sign = 1; while (scanf("%s %s", s1, s2) != EOF) { a = char2BIG(s1); b = char2BIG(s2); c = BIGSUB(a, b, &sign); if (sign == -1) printf("-"); printBIG(c); } return 0;}
代码示例
进制转换
#include <stdio.h>#include <string.h>
const char mod[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int A2dec(char *sol, int A) { int len = strlen(sol); int weight = 1; int ans = 0; for (int i = 0; i < len; i++) { if (sol[i] >= 'a' && sol[i] <= 'z') sol[i] -= 'a'-'A'; } for (int i = len-1; i > -1; i--) { int j; for (j = 0; j < strlen(mod); j++) if (mod[j] == sol[i]) break; ans += j*weight; weight *= A; } return ans;}
void dec2B(int dec,int B,char *ans) { char temp[50]; int i = 0; if (dec == 0) temp[i++] = '0'; while (dec) { temp[i++] = mod[dec%B]; dec /= B; } int k = 0; for (int j = i-1; j > -1; j--) { ans[k++] = temp[j]; } ans[k] = '\0';}
int main() { int A, B; // A为起始,B为目标 char sol[50]; // 转换数据 scanf ("%d %s %d", &A, &sol, &B); int dec; dec = A2dec(sol,A); char ans[50]; dec2B(dec,B,ans); printf("%s", ans); return 0;}
台阶走法
#include <stdio.h>#include <string.h>
typedef unsigned long long int ull;
#define SIZE 500
typedef struct { int cnt, v[SIZE];} BIGINT;
void printBIG(BIGINT b) { for (int i = 0; i < b.cnt; i++) printf("%d", b.v[b.cnt - 1 - i]); printf("\n");}
BIGINT int2BIG(int x) { BIGINT r = {0, {0}}; int flag = 0; //对0特判,但是没做0的add和mul while (x) { r.v[r.cnt++] = x % 10; x /= 10; flag = 1; } if (flag == 0) r.cnt = 1; return r;}
BIGINT string2BIG(char *s) { BIGINT r = {0, {0}}; r.cnt = strlen(s); for (int i = 0; i < r.cnt; i++) r.v[r.cnt - 1 - i] = s[i] - '0'; return r;}BIGINT mul(BIGINT S, BIGINT T) { if (S.cnt == 0 || T.cnt == 0) return int2BIG(0); BIGINT R = {S.cnt + T.cnt, {0}}; for (int i = 0; i < T.cnt; i++) { int t, k, j; int carry = 0; for (j = 0; j < S.cnt; j++) { t = S.v[j] * T.v[i] + carry + R.v[i + j]; R.v[i + j] = t % 10; carry = t / 10; } k = i + j; while (carry) { t = carry + R.v[k]; R.v[k] = t % 10; carry = t / 10; k++; } } if (R.v[S.cnt + T.cnt - 1] == 0) R.cnt--; return R;}
BIGINT add(BIGINT S, BIGINT T) { BIGINT R = {0, {0}}; int i, carry = 0; for (i = 0; i < S.cnt && i < T.cnt; i++) { int temp = (S.v[i] + T.v[i] + carry); R.v[i] = temp % 10; carry = temp / 10; } while (i < S.cnt) { int temp = S.v[i] + carry; R.v[i++] = temp % 10; carry = temp / 10; } while (i < T.cnt) { int temp = T.v[i] + carry; R.v[i++] = temp % 10; carry = temp / 10; } if (carry) R.v[i++] = carry % 10; R.cnt = i; return R;}
//ull hash[101] = {0};BIGINT hash[101];
int main() { for (int i = 0; i < 101; i++) { if (i <= 1) //hash[i] = 1; hash[i] = int2BIG(1); else if (i == 2) //hash[i] = 2; hash[i] = int2BIG(2); else if (i == 3) //hash[i] = 4; hash[i] = int2BIG(4); else if (i == 4) //hash[i] = 8; hash[i] = int2BIG(8); else { //hash[i] = hash[i - 1] + hash[i - 2] + hash[i - 3] + hash[i - 4]; BIGINT r1 = add(hash[i - 1], hash[i - 2]); BIGINT r2 = add(hash[i - 3], hash[i - 4]); hash[i] = add(r1, r2); } } int T; scanf("%d", &T); for (int i = 0; i < T; i++) { int ptA, ptB; //path A/B int stB, stS; //Start Building/Step int edB, edS; //End Building/Step scanf("%d %d %d %d %d %d", &ptA, &ptB, &stB, &stS, &edB, &edS); //ull ans; BIGINT ans = {0, {0}}; if (stB == edB) { if (ptA < stS || ptB > edS) { ans = hash[edS - stS]; } else { //ans = hash[edS - ptB] * hash[ptB - ptA] * hash[ptA - stS] + hash[edS - stS]; BIGINT r1 = mul(hash[edS - ptB], hash[ptB - ptA]); BIGINT r2 = mul(r1, hash[ptA - stS]); ans = add(r2, hash[edS - stS]); } } else if (stB != edB) { if (ptA < stS && ptB > edS || ptA > edS || ptB < stS) { /*B走廊在起点下方;A走廊在终点上方;AB包夹起点和终点*/ //ans = 0; ans = int2BIG(0); } else if (ptA < stS) { //ans = hash[ptB - stS] * hash[edS - ptB]; ans = mul(hash[ptB - stS], hash[edS - ptB]); } else if (ptB > edS) { //ans = hash[ptA - stS] * hash[edS - ptA]; ans = mul(hash[ptA - stS], hash[edS - ptA]); } else { //ans = hash[ptB - stS] * hash[edS - ptB] + hash[ptA - stS] * hash[edS - ptA]; BIGINT r1 = mul(hash[ptB - stS], hash[edS - ptB]); BIGINT r2 = mul(hash[ptA - stS], hash[edS - ptA]); ans = add(r1, r2); } } //printf("case #%d:\n%llu\n", i, ans); printf("case #%d:\n", i); printBIG(ans); } return 0;}
皇后问题
#include <stdio.h>
void Danger(int i, int j, char map[][200], int n) { /*Q的可攻击路径标记为D,遇到另外的Q则停止,并且把Q变为O*/ for (int k = i+1; k < n; k++) { // 下 if (map[k][j] == 'E') map[k][j] = 'D'; if (map[k][j] == 'Q') { map[k][j] = 'O'; break; } } for (int k = i-1; k > -1; k--) { // 上 if (map[k][j] == 'E') map[k][j] = 'D'; if (map[k][j] == 'Q') { map[k][j] = 'O'; break; } } for (int k = j+1; k < n; k++) { // 右 if (map[i][k] == 'E') map[i][k] = 'D'; if (map[i][k] == 'Q') { map[i][k] = 'O'; break; } } for (int k = j-1; k > -1; k--) { // 左 if (map[i][k] == 'E') map[i][k] = 'D'; if (map[i][k] == 'Q') { map[i][k] = 'O'; break; } } for (int k = i+1, l = j+1; k < n && l < n; k++, l++) { // 右下 if (map[k][l] == 'E') map[k][l] = 'D'; if (map[k][l] == 'Q') { map[k][l] = 'O'; break; } } for (int k = i-1, l = j+1; k > -1 && l < n; k--, l++) { // 右上 if (map[k][l] == 'E') map[k][l] = 'D'; if (map[k][l] == 'Q') { map[k][l] = 'O'; break; } } for (int k = i-1, l = j-1; k > -1 && l > -1; k--, l--) { // 左上 if (map[k][l] == 'E') map[k][l] = 'D'; if (map[k][l] == 'Q') { map[k][l] = 'O'; break; } } for (int k = i+1, l = j-1; k < n && l > -1; k++, l--) { // 左上 if (map[k][l] == 'E') map[k][l] = 'D'; if (map[k][l] == 'Q') { map[k][l] = 'O'; break; } }}
void Safe(int i, int j, char map[][200], int n); /*q的移动路径上若为E,标记为S,遇到Q变为S后停止,遇到O直接停止*/
int SafeCnter(char map[][200], int n) { /*统计地图中S的数目*/ int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) if(map[i][j] == 'S') cnt++; } return cnt;}
void Show(char map[][200], int n);
int main() { int n; char c; char map[200][200]; int Qpos[20000][2]; int Qind = 0; int qpos[2]; scanf("%d", &n); c = getchar(); /*读取地图*/ for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%c", &map[i][j]); if (map[i][j] == 'Q') { Qpos[Qind][0] = i; Qpos[Qind][1] = j; Qind++; } if (map[i][j] == 'q') { qpos[0] = i; qpos[1] = j; } } c = getchar(); } //printf("Qind:%d\n", Qind); /*标记危险格子*/ for (int i = 0; i < Qind; i++) { int Qi = Qpos[i][0], Qj = Qpos[i][1]; //printf("Qi:%d Qj:%d\n",Qi, Qj); Danger(Qi, Qj, map, n); } Safe(qpos[0], qpos[1], map, n); printf("%d\n",SafeCnter(map, n)); return 0;}
让算法落地:「编程思维与实践」课程笔记
https://leehenry.top/posts/debug_2_deploy/notesarchive/编思小抄/