1 子集和

https://oj.sdutacm.cn/onlinejudge3/contests/4288/problems/A

  1. 剪枝要单独return,否则即使有正解也会输出no solution
  2. dfs判断语句顺序问题,必须是应该先判断是否找到,因为找到的时候我们的下标是n。在判断>=n;
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
int a[maxn];
int st[maxn];
int sum = 0;
int n, c;
void dfs(int x)
{

	if (sum > c)
		return;
	//sum>c写在最前面高效
	//注意判断顺序,应该先判断是否找到,因为找到的时候我们的下标是n
	else if (sum == c)
	{
		for (int i = 0;i < n;i++)
		{
			if (st[i] == 1)
				cout << a[i] << " ";

		}
		exit(0);
	}
	else if (x >= n)
		return;
	
	
	sum += a[x];
	st[x] = 1;
	dfs(x + 1);
	sum -= a[x];
	st[x] = 0;
	dfs(x + 1);



}
int main() {
	cin >> n >> c;
	int total = 0;
	for (int i = 0;i < n;i++)
	{
		cin >> a[i];
		total += a[i];
	}
	if (total < c)
	{
		cout << "No Solution!" << endl;
		exit(0);
		//必须return,不然会输出没有结果

	}
	else if (total == c)
	{
		for (int i = 0;i < n;i++)
			cout << a[i] << " ";
		//必须return,不然会输出没有结果
		exit(0);
	}
	else {
		dfs(0);

	}
	cout << "No Solution!" << endl;

}

2 n后问题

https://www.luogu.com.cn/problem/P1219

  1. 因为有对角线所以数组需要开大一点,不能只开到15
  2. 按行依次放,所以我们要标记的是列,对角线,反对角,故应该是st1[i]
  3. 没有不放的选项,因为每一行都要放
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn =30;
//因为有对角线所以数组需要开大一点
int n;
int ans[maxn];
int st1[maxn];
int st2[maxn];
int st3[maxn];
int cnt = 0;
void dfs(int x)//第x行
{
	if (x > n)
	{
		cnt++;
		if (cnt <=3)
		{
			for (int i = 1;i <= n;i++)
			{
				cout << ans[i] << " ";
			}
			cout << endl;
		}
	}
	else
	{
		//这里枚举的是列
		for (int i = 1;i <= n;i++)
		{

			if (st1[i] != 1 && st2[x + i] != 1 && st3[i - x + n] != 1)
				//检查的是列号,所以是st1 i
			{
			ans[x] = i;
			st1[i] = 1;
			//是st1[i] 因为我们是一行一行放的所以我们只需要检查列号,而不是行号
			st2[x + i] = 1;
			st3[i - x+ n] = 1;
			dfs(x + 1);

			ans[x] = 0;
			st1[i] = 0;
			st2[x + i] = 0;
			st3[i - x + n] = 0;
			}
			

			
			//dfs(x + 1); n皇后每行都要放一个,不能跳过



		}
	}
}
int main()
{
	
	cin >> n;
	dfs(1);
	cout << cnt << endl;

}

3 整数变换

  1. 记得return
  2. tot记录最小步数
  3. 升级版bdfs
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn];
int tot = 1;
int n, m;
string s = "";
int  dfs(int x, int num)
{
	if (x > tot)return 0;
	if (num == m) return 1;
	else {
		for (int i = 0;i < 2;i++)
		{
			int temp = 0;
			if (!i)  temp = 3 * num;
			else temp = num / 2;
			if (dfs(x + 1, temp))
			{
				if (!i)s += 'f';
				else s += 'g';
				return 1;
			}

		}
		return 0;
		//需要return1,0;

	}


}
signed  main()
{
	cin >> n >> m;
	while (!dfs(0, n))tot++;
	cout << tot << endl;
	cout << s << endl;
	return 0;
}
posted on 2025-12-05 19:33  Hoshino1  阅读(3)  评论(0)    收藏  举报