深度优先搜索
//全排列 #include <stdio.h> int a[10], book[10], n; //注意:C语言全局变量在赋值前默认为0; void dfs (int step) { if (step == n + 1) { for (int i = 1; i < n + 1; i ++) { printf("%d", a[i]); } printf("\n"); return; } for (int i = 1; i <= n; i ++) { if (book[i] == 0) { a[step] = i; book[i] = 1; dfs(step + 1); book[i] = 0; } } return; } int main () { scanf("%d", &n); dfs(1); getchar();getchar(); return 0; }
//基本模型 void dfs (int step) { //判断边界 //尝试每一种可能 for (int i = 1; i < n; i ++) { //继续下一步 dsf(step + 1); } 返回 }
// ··· + ··· = ··· #include <stdio.h> int a[10], book[10], total; void dfs (int step) { if (step == 10) { int num1 = a[1] * 100 + a[2] * 10 + a[3]; int num2 = a[4] * 100 + a[5] * 10 + a[6]; int num3 = a[7] * 100 + a[8] * 10 + a[9]; if (num1 + num2 == num3) { total ++; printf("%d + %d = %d\n", num1, num2, num3); } return; } for (int i = 1; i < 10; i ++) { if (book[i] == 0) { a[step] = i; book[i] = 1; dfs(step + 1); book[i] = 0; } } return; } int main () { dfs(1); printf("total = %d", total / 2); getchar();getchar(); return 0; }
//解救小哈 #include <stdio.h> #include <limits.h> int next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int n, m, p, q, min = INT_MAX; int a[51][51], book[51][51]; void dfs (int x, int y, int step) { if (x == p && y == q) { if (step < min) { min = step; } return; } for (int k = 0; k < 4; k ++) { int tx = x + next[k][0]; int ty = y + next[k][1]; if (tx < 1 || tx > n || ty < 1 || ty > m) { continue; } if (a[tx][ty] == 0 && book[tx][ty] == 0) { book[tx][ty] = 1; dfs(tx, ty, step + 1); book[tx][ty] = 0; } } return; } int main () { int startx, starty; scanf ("%d%d", &n, &m); for (int i = 1; i <= n; i ++) for (int j = 1; j <= m; j ++) scanf("%d", &a[i][j]); scanf("%d%d%d%d", &startx, &starty, &p, &q); book[startx][starty] = 1; dfs(startx, starty, 0); printf("%d", min); return 0; }
P1037 [NOIP2002 普及组] 产生数
#include <stdio.h> #include <string.h> #include <math.h> int sum; int cnt[10]; int nxt[10][15]; int book[10]; int ans[30]; void dfs (int x) //深度优先搜索 { for (int i = 0; nxt[x][i] != 0; i ++) { if (book[nxt[x][i]] == 0) { sum ++; book[nxt[x][i]] = 1; dfs(nxt[x][i]); } } return; } void mul (int r) // 高精度乘低精度处理 { int up = 0; for (int i = 0; i < 30; i ++) { ans[i] = ans[i] * r + up; up = ans[i] / 10; ans[i] %= 10; } } int main () { char s[31]; scanf("%s", s); int len = strlen(s); int num[10] = {}; for (int i = 0; i < len; i ++) { num[s[i] - '0'] ++; } int k; scanf("%d", &k); int x; for (int i = 0; i < k; i ++) { scanf("%d", &x); scanf("%d", &nxt[x][cnt[x]++]); } int cot[10]; for (int i = 0; i < 10; i ++) { memset(book, 0, sizeof(book)); book[i] = 1; sum = 1; dfs(i); if (sum == 0) { sum = 1; } cot[i] = sum; } ans[0] = 1; for (int i = 0; i < 10; i ++) { for (int j = 0; j < num[i]; j ++) { mul(cot[i]); } } int flag = 0; for (int i = 30; i >= 0; i --) { if (flag == 0 && ans[i] == 0) { continue; } else { flag = 1; printf("%d", ans[i]); } } return 0; }
// 再解炸弹人 #include <stdio.h> char a[51][51]; bool book[51][51]; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int max = -1; int n, m; int getnum (int i, int j) { int sum = 0; int x = i; int y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } x --; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } x ++; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } y --; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } y ++; } return sum; } void dfs (int x, int y) { int sum = getnum(x, y); if (sum > max) { max = sum; } for (int k = 0; k < 4; k ++) { int tx = x + nxt[k][0]; int ty = y + nxt[k][1]; if (tx < 1 || tx > n - 2 || ty < 1 || ty > m - 2) { continue; } if (a[tx][ty] == '.' && book[tx][ty] == 0) { book[tx][ty] = 1; dfs(tx, ty); } } return; } int main () { int startx, starty; scanf("%d%d%d%d", &n, &m, &startx, &starty); for (int i = 0; i < n; i ++) { scanf("%s", a[i]); } book[startx][starty] = 1; dfs(startx, starty); printf("%d", max); return 0; }
// 宝岛探险 #include <stdio.h> int a[101][101]; bool book[101][101]; int n, m, sum; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; void dfs (int x, int y) { int tx, ty; for (int k = 0; k < 4; k ++) { tx = x + nxt[k][0]; ty = y + nxt[k][1]; if (tx < 1 || tx > n || ty < 1 || ty > m) { continue; } if (a[tx][ty] > 0 && book[tx][ty] == 0) { sum ++; book[tx][ty] = 1; dfs(tx, ty); } } return; } int main () { int startx, starty; scanf("%d%d%d%d", &n, &m, &startx, &starty); for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { scanf("%d", &a[i][j]); } } book[startx][starty] = 1; sum = 1; dfs(startx, starty); printf("%d", sum); return 0; }
cout
&cin
优化
using namespace std; ios::sync_with_stdio(false); cin.tie(NULL),cout.tie(NULL);
此段代码可优化cout
、cin
的效率
广度优先搜索
//解救小哈 #include <stdio.h> struct note { int x; int y; int f; int s; }; int main () { struct note que[10001]; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int book[101][101] = {}; //read int n, m; scanf("%d%d", &n, &m); int a[101][101]; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { scanf("%d", &a[i][j]); } } int startx, starty, p, q; scanf("%d%d%d%d", &startx, &starty, &p, &q); int head = 1; int tail = 1; que[tail].x = startx; que[tail].y = starty; que[tail].s = 0; que[tail].f = 0; tail ++; book[startx][starty] = 1; int flag = 0; while (head < tail) { for (int k = 0; k < 4; k ++) { int tx = que[head].x + nxt[k][0]; int ty = que[head].y + nxt[k][1]; if (tx < 1 || tx > n || ty > m || ty < 1) { continue; } if (a[tx][ty] == 0 && book[tx][ty] == 0) { book[tx][ty] = 1; que[tail].x = tx; que[tail].y = ty; que[tail].f = head; que[tail].s = que[head].s + 1; tail ++; } if (tx == p && ty == q) { flag = 1; break; } } if (flag) { break; } head ++; } if (flag) { printf("%d", que[tail - 1].s); } else { printf("No Way!"); } getchar();getchar(); return 0; }
// 再解炸弹人 #include <stdio.h> struct note { int x; int y; }; char a[51][51]; int getnum (int i, int j) { int sum = 0; int x = i; int y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } x --; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } x ++; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } y --; } x = i; y = j; while (a[x][y] != '#') { if (a[x][y] == 'G') { sum ++; } y ++; } return sum; } int main () { struct note que[2501]; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int n, m, startx, starty; scanf("%d%d%d%d/n", &n, &m, &startx, &starty); for (int i = 0; i < n; i ++) { scanf("%s", a[i]); } int head = 1; int tail = 1; que[tail].x = startx; que[tail].y = starty; tail ++; bool book[51][51]; book[startx][starty] = 1; int max = getnum(startx, starty); while (head < tail) { int tx, ty; for (int k = 0; k < 4; k ++) { tx = que[head].x + nxt[k][0]; ty = que[head].y + nxt[k][1]; if (tx < 1 || tx > n - 2 || ty < 1 || ty > m - 2) { continue; } if (a[tx][ty] == '.' && book[tx][ty] == 0) { book[tx][ty] = 1; que[tail].x = tx; que[tail].y = ty; tail ++; int sum = getnum(tx, ty); if (sum > max) { max = sum; } } } head ++; } printf("%d", max); return 0; }
// 宝岛探险 #include <stdio.h> struct note { int x; int y; }; int main () { struct note que[10001]; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int n, m, startx, starty; scanf("%d%d%d%d", &n, &m, &startx, &starty); int a[101][101]; bool book[101][101] = {}; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { scanf("%d", &a[i][j]); } } int head = 1; int tail = 1; que[tail].x = startx; que[tail].y = starty; tail ++; book[startx][starty] = 1; int sum = 1; while (head < tail) { int tx, ty; for (int k = 0; k < 4; k ++) { tx = que[head].x + nxt[k][0]; ty = que[head].y + nxt[k][1]; if (tx < 1 || tx > n || ty < 1 || ty > m) { continue; } if (a[tx][ty] > 0 && book[tx][ty] == 0) { sum ++; book[tx][ty] = 1; que[tail].x = tx; que[tail].y = ty; tail ++; } } head ++; } printf("%d", sum); return 0; }
Floodfill
漫水填充法(也称种子填充法)
求一个图中独立子图的个数
即查找周围与选中种子点相近(设置阈值)的种子点,并且将其入队,并进行扩展操作
多用于计算机图形学,图像分割识别,自动选中以及更改周围颜色相近的区域
// 宝岛探险 -- 小岛个数,以及染色 #include <stdio.h> int a[101][101]; bool book[101][101]; int n, m; int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; void dfs (int x, int y, int color) { a[x][y] = color; //染色 int tx, ty; for (int k = 0; k < 4; k ++) { tx = x + nxt[k][0]; ty = y + nxt[k][1]; if (tx < 1 || tx > n || ty < 1 || ty > m) { continue; } if (a[tx][ty] > 0 && book[tx][ty] == 0) { book[tx][ty] = 1; dfs(tx, ty, color); } } return; } int main () { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { scanf("%d", &a[i][j]); } } int num = 0; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { if (a[i][j] > 0) { num --; book[i][j] = 1; dfs(i, j, num); } } } for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { printf("%2d", a[i][j]); } printf("\n"); } printf("有%d个小岛!", -num); return 0; }