简单DFS举例

1,计算组合数

#include <iostream>
using namespace std;
int a[20], flag[20], n;
void dfs(int x) {
	if (x == n + 1) {
		for (int i = 1; i <= n; i++)cout << a[i] << " ";
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++) {
		if (flag[i] == 0) {
			a[x] = i;
			flag[i] = 1;
			dfs(x + 1);
			flag[i] = 0;
		}
	}
	return;
}
int main() {
	cin >> n;
	dfs(1);
	return 0;
}

2,在上题基础上增加了排序的DFS方法

#include <iostream>
using namespace std;
int a[20], flag[20], n, num_len, c = 0;
bool judge() {
	int tmp = n;
	for (int i = 1; i <= num_len; i++) {
		if (a[i] != tmp / (int)pow(10, num_len - i))return 0;
		tmp -= (tmp / (int)pow(10, num_len - i))*pow(10, num_len - i);
	}
	return 1;
}
void dfs(int x) {
	if (x == num_len + 1) {
		c++;
		if(judge())cout << c << endl;
		return;
	}
	for (int i = 1; i <= num_len; i++) {
		if (flag[i] == 0) {
			a[x] = i;
			flag[i] = 1;
			dfs(x + 1);
			flag[i] = 0;
		}
	}
	return;
}
int main() {
	cin >> num_len>>n;
	dfs(1);
	return 0;
}

3,进制类,这里以检查金币为例

蒜场生产金币的设备出了问题,使得最近生产的 10 批金币的重量出现了波动:本来金币的标准重量是 10 克,但现在有的可能是 11 克,有的可能 9 克,也有可能是 10克。

现在只知道同一批金币的重量是相同的,你的任务是要把每批的单枚金币的重量找出来。

你有一个电子秤,但只允许称量一次!

你从第 1 批中取 1 枚金币,从第 2 批取 3 枚,... 从第 i 批取 3^{i - 1}枚,...,从第 10 批取 3^9 枚,总共 29524 枚金币。将这 29524 枚金币放在电子秤上,得到了总重量。

这样就可以计算出来每一批金币的重量了,但是现在需要你写一个程序帮忙计算。

输入格式

输入包含一个 6 位的正整数 W(265716≤W≤324764),表示 29524 枚金币的总重量。

输出格式

输出一共 10 行,第 i 行代表第 i 批金币的单枚重量。

#include <bits/stdc++.h>
using namespace std;
int ans[10],n,c=0,i=0;
void solve(int sum){
    if(sum==n){
        for(int i=0;i<10;i++)cout<<ans[i]<<endl;
        return;
    }
    else if(c==10)return;
    for(int j=9;j<=11;j++)
    {
        ans[i++]=j;
        solve(sum+=j*pow(3,c++));
        sum-=j*pow(3,--c);
        i--;
    }
    return;
}
int main(){
    cin>>n;
    solve(0);
    return 0;
}

4,红与黑

蒜厂有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。

请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

输入格式

第一行是两个整数 W 和 H,分别表示 x 方向和 y 方向瓷砖的数量。W 和 H 都不超过 2020。

在接下来的 H 行中,每行包括 W 个字符。每个字符表示一块瓷砖的颜色,规则如下

1)'.':黑色的瓷砖;
2)'#':红色的瓷砖;
3)'@':黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。

输出格式

输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。

#include <iostream>
using namespace std;
int n,m;int c=0;
char f[20][21];
void dfs(int x,int y)
{
    f[x][y]='#';
    for(int dx=-1;dx<=1;dx++)
    {
        for(int dy=-1;dy<=1;dy++)
        {
            int nx=x+dx;int ny=y+dy;
            if(nx>=0&&nx<m&&ny>=0&&f[nx][y]=='.'){dfs(nx,y);c++;}
            else if(ny>=0&&ny<n&&f[x][ny]=='.'){dfs(x,ny);c++;}
        }
    }
    return ;
}
int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
            cin>>f[i][j];
    
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
            if(f[i][j]=='@')
            {
                dfs(i,j);
            }
    cout<<c+1;
}

5,打印数字圆环1到n,相邻数和为素数

#include <iostream>
#include <cmath>
using namespace std;
int a[10], flag[10], n = 0;
bool is_prime(int n) {
	if (n == 1)return 0;
	for (int i = 2; i <= sqrt(n); i++)if (n % i == 0)return 0;
	return 1;
}
bool check() {
	if(!is_prime(a[0]+a[n-1]))return 0;
	for (int i = 0; i < n - 1; i++)if (!is_prime(a[i] + a[i + 1]))return 0;
	return 1;
}
void dfs(int x) {
	if (x == n + 1) {
		if (check()) {
			for (int i = 0; i < n; i++)cout << a[i] << endl;
			cout << endl;
		}
		return;
	}
	for (int i = 1; i <= n; i++) {
		if (flag[i - 1] == 0) {
			a[x - 1] = i;
			flag[i - 1] = 1;
			dfs(x + 1);
			flag[i - 1] = 0;
		}
		
	}
	return;
}
int main() {
	cin >> n;
	dfs(1);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值