子序列和 c++ dfs

news/2024/7/20 20:56:29 标签: 深度优先, 算法, c++

题目描述

给定整数a1、a2、…an(1<=a1…an<=1000)。推断能否从中选出若干数,使它们的和恰好为k。

输入格式:

首先,n和k(1<=n<=25),n表示数的个数。k表示数的和。接着一行n个数。

输出格式:

假设和恰好能够为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成(若有多种可能情况,输出第一个满足条件的结果,请参考第二个样例)。否则“NO”。

输入样例:

4 13
1 2 4 7
12 10
6 2 4 7 5 3 2 1 6 9 10 2
12 58
6 2 4 7 5 3 2 1 6 9 10 2

输出样例:

YES
2 4 7
YES
6 2 2
NO

解题代码

定义变量

const int maxLength = 30;

int n, k;
//判断是否找到答案
bool flag = false;
//记录当前的数组和答案数组
vector<int>temp, answer;
//题目输入的数组
vector<int>nums(maxLength);
//表示对应下标的数组元素是否被访问,防止重复填入数组
vector<bool>vis(maxLength, false);

数据初始化

//防止多组数据间互相干扰,初始化数据
flag = false;
fill(vis.begin(), vis.begin() + maxLength, false);

数据读入

while (cin >> n >> k)
{
	for (int i = 0; i < n; i++)
	{
		cin >> nums[i];
	}
}

递归实现

//i表示上一个填入的数为nums[i],sum为当前temp数组中元素的和
//再次填数时从i开始,防止重复填入填过的数组导致超时
void dfs(int i, int sum)
{
    //如果找到答案或当前数组和大于k,都不需要继续递归填数,return返回
	if (flag || sum > k) return;
	//找到答案
	if (sum == k)
	{
		flag = true;
		answer = temp;
		return;
	}
//遍历数组,尝试nums[j]填入temp数组,更新sum的值为sum+nums[j]
//填入nums[s]的递归结束,再尝试取消填入nums[j]
	for (int j = i; j < n; j++)
	{
		if (!vis[j])
		{
			vis[j] = true;
			temp.push_back(nums[j]);
			dfs(j, sum + nums[j]);
			vis[j] = false;
			temp.pop_back();
		}
	}
}

输出结果

void showAnswer()
{
	if (flag)
	{
		cout << "YES" << endl;

		cout << answer[0];
		for (int i = 1; i < answer.size(); i++)
		{
			cout << ' ' << answer[i];
		}
		cout << endl;
	}
	else
	{
		cout << "NO" << endl;
	}
}

整体代码

#include <iostream>
#include <vector>

using namespace std;

const int maxLength = 30;

int n, k;
bool flag = false;
vector<int>temp, answer;
vector<int>nums(maxLength);
vector<bool>vis(maxLength, false);

void dfs(int i, int sum)
{
	if (flag || sum > k) return;

	if (sum == k)
	{
		flag = true;
		answer = temp;
		return;
	}
	
	for (int j = i; j < n; j++)
	{
		if (!vis[j])
		{
			vis[j] = true;
			temp.push_back(nums[j]);
			dfs(j, sum + nums[j]);
			vis[j] = false;
			temp.pop_back();
		}
	}
}

void showAnswer()
{
	if (flag)
	{
		cout << "YES" << endl;

		cout << answer[0];
		for (int i = 1; i < answer.size(); i++)
		{
			cout << ' ' << answer[i];
		}
		cout << endl;
	}
	else
	{
		cout << "NO" << endl;
	}
}

void solve()
{
	flag = false;
	fill(vis.begin(), vis.begin() + maxLength, false);

	for (int i = 0; i < n; i++)
	{
		cin >> nums[i];
	}

	dfs(0, 0);
	
	showAnswer();
}

int main()
{
	while (cin >> n >> k)
	{
		solve();
	}

	return 0;
}

http://www.niftyadmin.cn/n/1846480.html

相关文章

Flutter Checkbox CheckboxListTile

Flutter 系列文章 总体目录 Checkbox本身不包含任何状态&#xff0c;改变状态需要通过改变value的值改变。 属性说明valuetrue&#xff1a;选中状态。false&#xff1a;不选中状态。null&#xff1a;只有在tristatetrue时可设置此值tristate设置true时&#xff0c;value才能为…

Flutter Radio RadioListTile 单选框

Flutter 系列文章 总体目录 Radio是单选框&#xff0c;和checkbox一样本身不包含状态&#xff0c;当groupValue value时代表选中状态。 属性说明value 、groupValue一起控制是否为选中状态&#xff0c;当groupValue value时代表选中状态onChanged变化时回调activeColor激活…

Greedy Gift Givers c++

A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts of money. Each of these friends might or might not give some money to some or all of the other friends (although some might be cheap and give to no one). Likewise, each frie…

MarkDown上传本地图片出现的问题

本文为转载&#xff0c;原作者信息如下 作者&#xff1a;秋沐霖 来源&#xff1a;博客园 原文&#xff1a;https://www.cnblogs.com/HL-space/p/10893613.html 在写博客插入图片时&#xff0c;许多时候需要提供图片的url地址。作为菜鸡的我&#xff0c;自然是一脸懵逼。那么什么…

Flutter Switch

Flutter 系列文章 总体目录 Switch一个开关控件。 属性说明valuetrue&#xff1a;开 false&#xff1a;关onChanged变化时回调activeColor打开状态下颜色activeTrackColor打开状态下track颜色inactiveThumbColor关闭状态thumb颜色inactiveTrackColor关闭状态track颜色activeT…

tar.gz和tar.xz文件

本文为转载 原作者链接&#xff1a;https://blog.csdn.net/Architect_CSDN/article/details/102489050 侵删 1&#xff0c;.tar文件 tar -cvf 压缩tar -xvf 解压例如&#xff1a;tar -xvf mysql-8.0.16-linux-glibc2.12-x86_64.tar2&#xff0c;.xz文件 xz -d 解压&am…

拉马车 c++

题目描述 小的时候&#xff0c;你玩过纸牌游戏吗&#xff1f; 有一种叫做"拉马车"的游戏&#xff0c;规则很简单&#xff0c;却很吸引小朋友。 其规则简述如下&#xff1a; 假设参加游戏的小朋友是 A 和 B &#xff0c;游戏开始的时候&#xff0c;他们得到的随机…

Flutter Slider

Flutter 系列文章 总体目录 属性说明value控件的位置onChanged变化时回调onChangeStart滑动开始时回调一次onChangeEnd滑动结束时回调一次min最小值max最大值divisions分为几块&#xff0c;比如设置为5&#xff0c;Slider只能滑动到5个位置labeldivisions设置显示在节点上的lab…