深度优先搜索
//全排列
#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;
}









