int a[200],b[200]; memset(a,0, sizeof(a)); memset(b, 0, sizeof(b)); //给定数字 int lena = num1.length(); int lenb = num2.length(); //多个数字,或者未给定 int lena = 1; int lenb = 1;
2、输入高精度数(根据题目要求来进行,有时还需要先去除前导零(倒序))
1 2 3 4
//去除前导零 for (int i = 0; i < lena; i++) { a[i] = num1[lena-1-i]-'0'; }
//x为进位 int x = 0; int len = max(lena, lenb); for (int i = 0; i < len; i++) { c[i] = a[i]+b[i] + x; x = c[i] / 10; c[i] = c[i] % 10; } if (x > 0) { c[len] = x; //这里的x = x / 10;可以不加,因为如果是加法的话,是不会存在加到最高位时,x超过两位数的情况 x = x / 10; len++; }
4、去除前导0
1 2 3 4
//lena - 1 > 0是为了在最后一位等于0时,保留这个0 while (c[len - 1] == 0 && len - 1 > 0) { len--; }
5、输出
1 2 3 4
//倒序输出 for (int i = len - 1; i >= 0; i--) { cout << c[i]; }
#include<bits/stdc++.h> usingnamespace std; voidchen(int b[], int& lenb, int n){ int x = 0; for (int i = 0; i < lenb; i++) { b[i] = b[i] * n + x; x = b[i] / 10; b[i] = b[i] % 10; }
while (x != 0) { b[lenb] = x % 10; x = x / 10; lenb++; } }
voidjia(int a[], int& lena, int b[], int lenb){ lena = max(lena, lenb); int x = 0; for (int i = 0; i < lena; i++) { a[i] = a[i] +b[i] + x; x = a[i] / 10; a[i] = a[i] % 10; }
if (x) { a[lena] = x; lena++; } } intmain(){ int n; cin >> n; int a[10000]; memset(a, 0, sizeof(a));
a[0] = 0; int lena = 1;
int b[10000]; memset(b, 0, sizeof(b)); b[0] = 1; int lenb = 1;
for (int i = 1; i <=n; i++) { chen(b, lenb, i); jia(a, lena, b,lenb); }
while (a[lena - 1] == 0 && lena - 1 > 0) { lena--; } for (int i = lena - 1; i >= 0; i--) { cout << a[i]; } return0; }
intmain(){ string num = "00000000000011111111112321321312312312321"; int b = 1234; int a[100];
memset(a,0, sizeof(a)); int lena = num.length(); //为什么倒序取该数组 //因为num前面会有0出现,这样才能从a[0]开始取各个位置与b相加 for (int i = 0; i < lena; i++) { a[i] = num[lena-1-i]-'0'; }
int x = 0; a[0] = a[0] + b;
//做进位,以及把各个位置相加,流程结束会得到num与b相加的结果,只对低精度部分进行变化 //更高位,直接逆序输出即可 for (int i = 0; i < lena; i++) { a[i] = a[i] + x; x = a[i] / 10; a[i] = a[i] % 10; } //为了意外的情况,高精度的位数没有低精度的位数高,比如1(高精度)+10000(低精度) while (x != 0) { a[lena] = x % 10; x = x / 10; lena++; } //去除前导0 //lena - 1 > 0是为了在最后一位等于0时,保留这个0 while (a[lena - 1] == 0 && lena - 1 > 0) { lena--; } for (int i = lena - 1; i >= 0; i--) { cout << a[i]; } return0; }
int a[200],b[200]; memset(a,0, sizeof(a)); memset(b, 0, sizeof(b)); //给定数字 int lena = num1.length(); int lenb = num2.length(); //多个数字,或者未给定 int lena = 1; int lenb = 1;
2、输入高精度数(根据题目要求来进行,有时还需要先去除前导零(倒序))
1 2 3 4
//去除前导零 for (int i = 0; i < lena; i++) { a[i] = num1[lena-1-i]-'0'; }
//x为进位 int x = 0; int len = max(lena, lenb); //当第一次减去的值为负数时,则需要减去进位,比如第二位要还第一位的向它借的1 for (int i = 0; i < len; i++) { c[i] = a[i] - b[i] - x; x = 0; //以下借位的步骤,每次循环如果a[i]还是小于0,则需要继续往前一位借1 while (c[i] < 0) { x++; c[i] = c[i] + 10; } }
4、去除前导0
1 2 3 4
//lena - 1 > 0是为了在最后一位等于0时,保留这个0 while (c[len - 1] == 0 && len - 1 > 0) { len--; }
5、输出
1 2 3 4
//倒序输出 for (int i = len - 1; i >= 0; i--) { cout << c[i]; }
int a[200],b[200]; memset(a,0, sizeof(a)); memset(b, 0, sizeof(b)); //给定数字 int lena = num1.length(); int lenb = num2.length(); //多个数字,或者未给定 int lena = 1; int lenb = 1;
2、输入高精度数(根据题目要求来进行,有时还需要先去除前导零(倒序))
1 2 3 4
//除法的高精度是唯一不需要倒序取的算法 for (int i = 0; i < lena; i++) { a[i] = num[i] - '0'; }
//t为新的被除数,c[i]为商的每一位,x为余数 //比如我们130除以13,第一次循环a[0]为0*10+1=1,c[0]=1/13=0,x=1%13=0 for (int i = 0; i < len; i++) { t = x * 10 + a[i]; c[i] = t / b; x = t % b; }
4、去除前导0+输出
1 2 3 4 5 6 7 8
//下面的代码作用为将前导0删除 for (int i = 0; i < len; i++) { //首先使用一个for循环遍历结果数组c,如果当前位不为0或者之前已经输出过一位数字(flag为1),则输出该位数字,并将flag设置为1,表示最高位已经输出。 if (c[i] != 0 || flag == 1) { cout << c[i]; flag = 1; } }
intmain(){ string num ; int b = 13; int a[100],c[100];
cin >> num; memset(a, 0, sizeof(a)); int lena = num.length(); //除法的高精度是唯一不需要倒序取的算法 for (int i = 0; i < lena; i++) { a[i] = num[i] - '0'; } memset(c, 0, sizeof(c)); int len = lena;
int x = 0, t = 0; int flag = 0;
//t为新的被除数,c[i]为商的每一位,x为余数 //比如我们130除以13,第一次循环a[0]为0*10+1=1,c[0]=1/13=0,x=1%13=0 for (int i = 0; i < len; i++) { t = x * 10 + a[i]; c[i] = t / b; x = t % b; }
//下面的代码作用为将前导0删除 for (int i = 0; i < len; i++) { //首先使用一个for循环遍历结果数组c,如果当前位不为0或者之前已经输出过一位数字(flag为1),则输出该位数字,并将flag设置为1,表示最高位已经输出。 if (c[i] != 0 || flag == 1) { cout << c[i]; flag = 1; } } cout << endl; //最后需要判断flag的值,如果为0,说明结果为0,需要输出一个0。否则就已经将结果输出完毕了,直接结束程序即可。 if (flag == 0) { cout << 0; cout << endl; } cout << x; return0; }
intmain(){ string a; int c[31],len,t,x,flag; flag = 0; cin >> a; len = a.size(); memset(c, 0, sizeof(c)); for (int i = 0; i < len; i++) { c[i] = a[i] - '0'; }
for (int s = 2; s <= 9; s++) { x = 0; for (int i = 0; i < len; i++) { t = x * 10 + c[i]; x = t % s; } if (x == 0) { cout << s << " "; flag = 1; } } if (flag == 0) { cout << "none"; } return0; }
//如果余数d比除数b大,则返回true boolbig(int d[], int lend, int b[], int lenb){ //下面是lenb、lend相等的情况 for (int i = lend - 1; i >= 0; i--) { ////这里的条件很关键,d[lend - 1]!=0这个条件如果不加,就会出现d数组取值={0,0},但是lend为2大于lenb为1,返回了ture,而不断减去b,导致错误(QAQ这个条件卡了三个半小时) if (lend > lenb&&d[lend - 1]!=0) returntrue; if (lend < lenb) returnfalse; if (d[i] > b[i]) { returntrue; } elseif (d[i] < b[i]) { returnfalse; } //重复循环 else { continue; } } //每一位相等的情况下,则返回false returntrue; }
//将余数d-除数b,执行减法后,d的长度将改变,必须通过引用(&)传递出来 voidjianfa(int d[], int& lend, int b[]){ //x是借位,初始第0位是没有借位的 int x = 0; //这里是正序的因为减法从原本数字的最低位开始,而数组是逆序存放数字的 for (int i = 0; i < lend; i++) { d[i] = d[i] - b[i] - x; if (d[i] < 0) { d[i] += 10; x = 1; } else { x = 0; } } //修改余数d的长度 while (d[lend - 1] == 0 && lend - 1 > 0) { lend--; } }
intmain(){ string num1; string num2; //a数组是被除数,b数组是除数,c数组是商,d数组是余数 int a[300], b[300], c[300],d[300];
cin >> num1 >> num2; int lena = num1.length(); int lenb = num2.length(); memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); memset(d, 0, sizeof(d)); //倒序取数组a for (int i = 0; i < lena; i++) { a[i] = num1[lena - 1 - i] - '0'; } //倒序取数组b for (int i = 0; i < lenb; i++) { b[i] = num2[lenb - 1 - i] - '0'; }
//余数长度为0 int lend = 0; //从被除数的最高位开始 for (int i = lena - 1; i >= 0; i--) { //1.将余数全部位数向右移动一位,因为一次循环后,相当于有一位已经完成了除法,所以有余数的话,向后退一位,而先前的那一位,后面会塞下新的a[i],相当于把余数放大10倍(等同于高精度除单精度中的x*10步骤) for (int j = lend - 1; j >= 0; j--) { d[j + 1] = d[j]; } //2.获得余数的新第0位 d[0] = a[i]; //3.余数的位数多加一位,因为上面最前面多加了一位 lend++; //4.将余数d和除数b相减,每减一次,则第i位商+1 while (big(d, lend, b, lenb)) { jianfa(d, lend, b); c[i]++; } } //商c的长度不超过被除数a的长度 int lenc = lena; //去除前导0 while (c[lenc - 1] == 0 && lenc - 1 > 0) { lenc--; } while (d[lend - 1] == 0 && lend - 1 > 0) { lend--; } for (int i = lenc - 1; i >= 0; i--) { cout << c[i]; } cout << endl; for (int i = lend - 1; i >= 0; i--) { cout << d[i]; }
return0; }
排序
冒泡排序
核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//冒泡算法 voidbubble_sort(int a[], int n){ for (int i = 0; i < n; i++) { int flag = false; //j从0开始,但是要小于n-i-1,是因为无序区元素个数为n-i,而一共要比较n-i-1次 for (int j = 0; j < n - i - 1; j++) { //此处为小于,所以为递增 if (a[j] < a[j + 1]) { swap(a[j], a[j + 1]); flag = true; } } //全程无交换,则说明本来就是有序的,不需要浪费时间进行循环,直接跳出循环 if (!flag) { break; } } }
voidprint(int a[], int n){ for (int i = 0; i < n; i++) { cout << a[i]<<" "; } }
//冒泡算法 voidbubble_sort(int a[], int n){ for (int i = 0; i < n; i++) { int flag = false; for (int j = 0; j < n - i - 1; j++) { if (a[j] < a[j + 1]) { swap(a[j], a[j + 1]); flag = true; } } //全程无交换,则说明本来就是有序的,不需要浪费时间进行循环,直接跳出循环 if (!flag) { break; } } }
voidprint(int a[], int n){ for (int i = 0; i < n; i++) { cout << a[i] << " "; } }
voidbubble_sort(int a[], int n){ for (int i = 0; i < n; i++) { int flag = false; for (int j = 0; j < n - i - 1; j++) { if (a[j] < a[j + 1]) { swap(a[j], a[j + 1]); flag = true; } } //全程无交换,跳出循环 if (!flag) { break; } } } voidbubble_sort2(int a[], int n){ for (int i = 0; i < n; i++) { int flag = false; for (int j = 0; j < n - i - 1; j++) { if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); flag = true; } } //全程无交换,跳出循环 if (!flag) { break; } } }
intmain(){ int a[10], b[10], c[10], cnt = 0, cntc = 0; int n = 10;
for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { if (a[i] % 2 == 1) { b[cnt++] = a[i]; } else { c[cntc++] = a[i]; } }
voidprint(int a[], int n){ //为了题目格式要求,对输出函数做一点改变 cout << a[0]; for (int i = 1; i < n; i++) { cout << "," << a[i]; } }
voidbubble_sort(int a[], int n){ for (int i = 0; i < n; i++) { int flag = false; for (int j = 0; j < n - i - 1; j++) { if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); flag = true; } } //全程无交换,跳出循环 if (!flag) { break; } } }
intmain(){ int a[500], b[500], cnt = 0; int n;
cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { if (a[i] % 2 == 1) { b[cnt++] = a[i]; } }
bubble_sort(b, cnt);
print(b, cnt); return0; }
插入排序
核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
voidinsertsort(int a[], int n){ //注意这个循环范围,因为第一个无序区的元素下标为1,而最后一个下标为n-1 for (int i = 1; i < n; i++) { int j = i - 1; //t为需要排序的数组a的元素 int t = a[i]; //t找位置的过程,在过程中数组t前面的元素位置往后撤 //此处大于,所以为递增 while (j >= 0 && a[j] > t) { a[j + 1] = a[j]; j--; } //t通过不断前移找到正确的位置 //而a[j+1]要么是第一个位置,j=-1时,a[j+1]=a[0] //要么此时a[j]<t了,排序就已经按照递增来排序了 a[j + 1] = t; } }
int a[MAXN], b[MAXN], c[MAXN]; // 数组,用于存储斐波那契数列中的三个数
// 加法函数,将数组 a 和 b 相加,结果存储在数组 c 中 voidadd(int a[], int b[], int c[]){ int carry = 0; // 进位 for (int i = 0; i < MAXN; i++) { c[i] = a[i] + b[i] + carry; // 计算 c[i],等于 a[i] + b[i] + 进位 carry = c[i] / 10; // 计算进位,即 c[i] 除以 10 的商 c[i] %= 10; // 取个位数,即 c[i] 除以 10 的余数 } }
// 计算斐波那契数列的第 n 项 voidfbnq(int n){ // 初始化,将数组 a 和 b 的所有元素都赋值为 0,数组 c 的第一个元素赋值为 1 memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); a[0] = b[0] = 1;
// 从第三项开始计算,依次计算出第 3 到第 n 项 for (int i = 3; i <= n; i++) { add(a, b, c); // 计算下一个数,将 a 和 b 相加,结果存储在数组 c 中 memcpy(a, b, sizeof(b)); // 用 b 更新 a,将数组 b 的所有元素复制到数组 a 中 memcpy(b, c, sizeof(c)); // 用 c 更新 b,将数组 c 的所有元素复制到数组 b 中 }
// 输出结果,逆序输出数组 c 中的元素,即为斐波那契数列的第 n 项 int pos = MAXN - 1; // pos 初始值为数组的最后一个元素的下标 while (pos > 0 && c[pos] == 0) pos--; // 找到最高位,即从后往前第一个非零元素的下标 for (int i = pos; i >= 0; i--) { cout << c[i]; // 逆序输出数组 c 中的元素 } cout << endl; }
for (int i = s; i <= n; i++) { //非叶子结点(通过dfs(n / i, i)进行递归) if (n%i==0) { dfs(n / i, i); } //剪枝(n%i!=0的情况) else { continue; } } return; } intmain() { int n,m; cin>>n; for (int i = 1; i <= n; i++) { ans = 0; cin >> m; dfs(m, 2); cout << ans << endl; } return0; }
//CSDN: #include<bits/stdc++.h> usingnamespace std; int n, m, n1, m1, n2, m2, d = 0;//n行m列 char a[100][100];//保存二维数组 int e[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };//分别表示上下左右 voidfun(int x, int y) { if (d == 1) { return; } if (x == n2 && y == m2) { d = 1; return; } for (int i = 0; i < 4; i++)//循环判断上下左右 { int x1 = x + e[i][0];//计算下一个点的坐标 int y1 = y + e[i][1];//计算下一个点的坐标 if (x1 >= 0 && y1 >= 0 && x1 < n && y1 < n && a[x1][y1] != '#')//判断边界,判断是否访问过,判断是否可以通过 { a[x1][y1] = '#';//走过就标记为不能走 fun(x1, y1);//进入下一个点 } } } intmain() { cin >> m; while (m--) { cin >> n; for (int i = 0; i < n; i++) { for (int k = 0; k < n; k++) { cin >> a[i][k]; } } cin >> n1 >> m1 >> n2 >> m2; d = 0; if (a[n1][m1] == '#' || a[n2][m2] == '#') { cout << "NO" << endl; continue; } fun(n1, m1); if (d == 1) cout << "YES" << endl; else cout << "NO" << endl; } return0; }
//老师的dfs: #include<bits/stdc++.h> usingnamespace std; int n; char a[101][101];//保存二维数组 int dir[4][2] = { {-1,0},{0,-1},{1,0},{0,1} };//分别表示上下左右 bool vis[101][101]; structpoint { int x; int y; }; point a1; point a2; bool flag;
boolin(point k){ if (k.x < n && k.x >= 0 && k.y < n && k.y >= 0) { returntrue; } else { returnfalse; } }
voiddfs(point k){ for (int i = 0; i < 4; i++)//循环判断上下左右 { //终止条件,剪枝,防止超时 if (flag) { return; } point t; t.x = k.x + dir[i][0];//计算下一个点的坐标 t.y = k.y + dir[i][1];//计算下一个点的坐标 if (in(t)&&!vis[t.x][t.y]&&a[t.x][t.y]=='.'){//判断边界,判断是否访问过,判断是否可以通过 vis[t.x][t.y] = true;
if (t.x == a2.x && t.y == a2.y) { flag = true; return; }else { dfs(t); }
} } } intmain(){ int t; cin >> t; for(int i=0;i<t;i++){ cin >> n; for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ cin >> a[i][j]; } } cin >> a1.x >> a1.y >> a2.x >> a2.y;
intmain(){ //外层的while循环是因为可能存在多组数据,需要持续输出 while (true) { cin >>x>>y; //当在一行中读入的是两个零时,表示输入结束,这里的return 0来跳出while循环 if (x == 0 && y == 0) { return0; } //循环输入棋盘的具体情况,这里注意i<y而不是i<x,原因是i指代的应该是列数 for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { cin >> a[i][j]; //遇到'@',记录出现的位置,进行深度搜索 if (a[i][j] == '@') { a1.x = i; a1.y = j; } } } //注意重置vis语句的位置,因为后续还可能有新一组的输入 memset(vis, 0, sizeof(vis)); //这里是因为题目中要求:记数时包括初始位置的瓷砖 num = 1;
dfs(a1);
cout << num<<endl; } return0; }
//自己改的bfs: //bfs: //1、建立队列queue<point> q; //2、队尾插入传入元素q.push(k); //3、队列不为空while (!q.empty()) //4、队首元素传入point k = q.front(); //5、队尾插入新的元素q.push(t);(相当于dfs的dfs(t)) //6、队首元素删除q.pop();(放在while层的下一级与for同级) #include<bits/stdc++.h> usingnamespace std; int x, y;
char a[21][21];//保存二维数组 int dir[4][2] = { {-1,0},{0,-1},{1,0},{0,1} };//分别表示上下左右 bool vis[21][21]; structpoint { int x; int y; };
point a1; point a2; bool flag; int num = 0;
//判断是否在棋盘的界内 boolin(point k){ if (k.x < y && k.x >= 0 && k.y < x && k.y >= 0) { returntrue; } else { returnfalse; } }
voidbfs(point k){ queue<point> q; q.push(k); //循环判断上下左右 while (!q.empty()) { for (int i = 0; i < 4; i++) { point k = q.front(); point t; t.x = k.x + dir[i][0];//计算下一个点的x坐标 t.y = k.y + dir[i][1];//计算下一个点的y坐标