例题一
题目描述给定整数a1、a2、…an,判断是否可以从中选出若干数,使它们的和恰好为K。输入首先,n和k,n表示数的个数,k表示数的和。
接着一行n个数。(1<=n<=20,保证不超int范围)输出如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”样例输入
4 13
1 2 4 7
样例输出
YES
2 4 7
#include<bits/stdc++.h>
using namespace std;
//全局变量
int n,k;
int a[30]={0};
int v[30]={0};
//函数声明
void solve();
bool dfs(int i,int sum);
int main(){
// 输入
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
//解决此题的函数
solve();
return 0;
}
void solve(){
if(dfs(0,0)){//i=0,sum=0;
for(int i=0;i<n;i++){
if(v[i]) cout<<a[i]<<" ";
}
}
else printf("No\n");
}
//深度优先搜索 ,递归
bool dfs(int i,int sum){//已经从前i项得到了和sum,然后对于i项之后的进行分支
// 如果前n项都计算过了
if(i==n) return sum==k;//如果相等就返回1,否则就返回0;
// 不加上a[i]的情况
if(dfs(i+1,sum)) return true;//dfs函数是一个bool值,只有当sum==k,才会返回true;
// 加上a[i]的情况
if(dfs(i+1,sum+a[i])){
v[i]=1; //第i项是否要加,只有方便输出到底是那几个相加的,26,27行
return true;
}
// 无论是否加上a[i]都不能凑成k就返回false
return false;
}
例题二
凑算式
如图,这个算式中AI代表19的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
答案是 29
#include <bits/stdc++.h>
using namespace std;
void dfs(int m);
bool check();
int a[20];
int vis[20];
int sum;
int main()
{
dfs(0);
cout << sum;
return 0;
}
void dfs(int m)
{
if (m > 8 && check())
{
sum++;
}
for (int i = 1; i <= 9; i++)
{
if (!vis[i])
{
vis[i] = true;
a[m] = i;
dfs(m + 1);
vis[i] = false;
}
}
}
bool check()
{
int x = a[0] * a[2] * (a[6] * 100 + a[7] * 10 + a[8]);
int y = a[1] * (a[6] * 100 + a[7] * 10 + a[8]);
int z = a[2] * (a[3] * 100 + a[4] * 10 + a[5]);
int d = 10 * a[2] * (a[6] * 100 + a[7] * 10 + a[8]);
if (x + y + z == d)
{
return 1;
}
return 0;
}
例题三
九数组分数
1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
#include <bits/stdc++.h>
using namespace std;
int a, b;
int x[9] = {0};
int vis[9] = {0};
bool check()
{
a = x[0] * 1000 + x[1] * 100 + x[2] * 10 + x[3];
b = x[4] * 10000 + x[5] * 1000 + x[6] * 100 + x[7] * 10 + x[8];
if (a * 3 == b)
return 1;
else
return 0;
}
void dfs(int m)
{
if (m > 8 && check())
{
printf("%d/%d\n", a, b);
}
for (int i = 1; i <= 9; i++)
{
if (!vis[i])
{
vis[i] = 1;
x[m] = i;
dfs(m + 1);
vis[i] = 0;
}
}
}
int main()
{
dfs(0);
return 0;
}
例题四
六角填数
如图【1.png】所示六角形中,填入1~12的数字。
使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号(*)位置所代表的数字是多少?
#include <bits/stdc++.h>
using namespace std;
#define N 12
int a[N] = {1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3};
bool vis[N + 1];
bool check()
{
int sum[6];
sum[0] = a[0] + a[2] + a[5] + a[7];
sum[1] = a[1] + a[2] + a[3] + a[4];
sum[2] = a[1] + a[5] + a[8] + a[11];
sum[3] = a[7] + a[8] + a[9] + a[10];
sum[4] = a[0] + a[3] + a[6] + a[10];
sum[5] = a[4] + a[6] + a[9] + a[11];
for (int i = 0; i + 1 < 6; i++)
{
if (sum[i] != sum[i + 1])
return 0;
}
return 1;
}
void dfs(int m)
{
if (m == 0 || m == 1 || m == 11)
dfs(m + 1);
if (m > 11 && check())
{
cout << a[5];
}
for (int i = 1; i <= 12; i++)
{
if (vis[i] != 0)
continue; //自动略过已经被占用的数字
else
{
a[m] = i;
vis[i] = true;
dfs(m + 1);
vis[i] = false;
}
}
}
int main()
{
memset(vis, false, sizeof(vis));
vis[1] = vis[3] = vis[8] = true;
dfs(0);
return 0;
}