提示:题目描述自行根据前面的编号去洛谷搜索
P1036 [NOIP2002 普及组] 选数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 30;
int num[N];
int state[N];//-1表示没选,其余代表选了那个数
int n, k;
int cnt;
void dfs(int depth, int start){//组合类型枚举
if(depth > k){//已经选了k个数,递归截止,开始判断搜索到的结果是否符合题意
int sum = 0;
for(int i = 1; i <= k; i++){//求和
sum += state[i];
}
bool flag = true;
for(int i = 2; i <= sum - 1; i++){//判断其和是否为素数
if(sum % i == 0){
flag = false;
break;
}
}
if(flag == true){//如果是素数则计数加一
cnt++;
}
return;
}
for(int i = start; i <= n; i++){
state[depth] = num[i];//递归到下一层
dfs(depth + 1, i + 1);
state[depth] = -1;//恢复现场
}
}
int main(){
memset(state, -1, sizeof state);
cin >> n >> k;
for(int i = 1; i <= n; i++){
cin >> num[i];
}
dfs(1, 1);
cout << cnt << endl;
return 0;
}
P2089 烤鸡
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;
int state[N];
int data[60000][N];
int n, cnt, data_p = 1;
void dfs(int depth, int sum){//每一层表示某种调料选多少克
if(sum > n){
return;
}//搜索到第10层也就是第10种调料结束
if(depth > 10 && sum != n){
return;
}
if(depth > 10 && sum == n){
cnt++;
for(int i = 1; i <= 10; i++){
data[data_p][i] = state[i];
}
data_p++;
return;
}
else{
for(int i = 1; i <= 3; i++){
state[depth] = i;
dfs(depth + 1, sum + i);
state[depth] = 0;//恢复现场
}
}
}
int main(){
cin >> n;
dfs(1, 0);
cout << cnt << endl;
for(int i = 1; i <= cnt; i++){
for(int j = 1; j <= 10; j++){
cout << data[i][j] << " ";
}
cout << endl;
}
return 0;
}
P1149 [NOIP2008 提高组] 火柴棒等式
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1000;
int base_num[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};//用于保存0-9这10个数字所需要的火柴棒个数
int num[N];
int state[10];//用于保存当前搜索到的方案-1表示没考虑
int n;
int cnt;
void dfs(int depth, int sum){
if(sum > n){//剪枝
return;
}
if(depth > 3){
if(sum == n && state[1] + state[2] == state[3]){//如果搜索到的方案满足题意则方案数加一
cnt++;
}
else{
return;
}
}
else{
for(int i = 0; i <= 1000; i++){
state[depth] = i;//递归到下一层
dfs(depth + 1, sum + num[i]);
state[depth] = -1;//恢复现场
}
}
}
int main(){
memset(state, -1, sizeof state);
for(int i = 0; i <= 1000; i++){
int a = i % 10; //取个位
int b = (i / 10) % 10; //取十位
int c = i / 100; //取百位
if(c == 0 && b == 0 && a == 0){
num[i] = base_num[0];
}
else if(c == 0 && b == 0){
num[i] = base_num[a];
}
else if(c == 0){
num[i] = base_num[a] + base_num[b];
}
else{
num[i] = base_num[a] + base_num[b] + base_num[c];
}
}
cin >> n;
n -= 4;
dfs(1, 0);
cout << cnt << endl;
return 0;
}
P1088 [NOIP2004 普及组] 火星人
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 10010;
int num[N];
int input_num[N];
bool state[N];
int n, m, cnt;
int flag;
void dfs(int depth){
if(flag == true){//只输出一次,剪枝
return;
}
if(depth > n){
cnt++;
if(cnt == m + 1){
for(int i = 1; i <= n; i++){
cout << num[i] << " ";
}
flag = true;
}
return;
}
for(int i = 1 ; i <=n; i++){
if(cnt == 0){
i = input_num[depth];//初始化dfs位置(起点)
}
if(state[i] == true){
continue;
}
state[i] = true;
num[depth] = i;
dfs(depth + 1);
state[i] = false;//恢复现场
num[depth] = 0;
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> input_num[i];
}
dfs(1);
return 0;
}
P2036 [COCI2008-2009 #2] PERKET
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 20;
int state[N];//-1表示没考虑,0表示没选,1表示选
int s[N], b[N];
int n;
int res = 0x7FFFFFFF;
void dfs(int depth){
if(depth > n){
int sum_s = 1, sum_b = 0; //酸度乘积与苦度之和
bool flag = false;//判断是否n中调料都没有选
for(int i = 1; i <= n; i++){
if(state[i] == 1){
flag = true;
sum_s = sum_s * s[i];
sum_b = sum_b + b[i];
}
}
if(flag == true){
res = min(res, abs(sum_s - sum_b));
}
return;
}
state[depth] = 1;//考虑
dfs(depth + 1);
state[depth] = -1;//恢复
state[depth] = 0;//不考虑
dfs(depth + 1);
state[depth] = -1;//恢复
}
int main(){
memset(state, -1, sizeof state);
cin >> n;
for(int i = 1; i <= n; i++){
cin >> s[i] >> b[i];
}
dfs(1);
cout << res << endl;
return 0;
}