算法打卡Day1
回溯法
1、求解组合问题

思路一:每个数字都有选和不选两种可能
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
vector<int> a;
void dfs(int n,int r,int start){
if(start>n)
return;
dfs(n,r,start+1);
a.push_back(start);
if(a.size()==r){
cout<<'(';
for(int i=0;i<a.size();i++){
cout<<a[i];
if(a.size()!=1&&i!=a.size()-1)
cout<<',';
}
cout<<')';
}
dfs(n,r,start+1);
a.pop_back();
}
int main(){
int n,r;
while(1){
cin>>n;
if(!n)break;
cin>>r;
dfs(n,r,1);
}
return 0;
}
思路二:第x个位置可以选择(r[i-1]+1)~n的元素
#include <stdio.h>
#include <vector>
using namespace std;
int n=5, r=3; vector<int> path;
void dfs(int i, int num) {
if (num==r) {
printf("(%d",path[0]);
for (int i=1; i<path.size(); i++)
printf(",%d", path[i]);
printf(")"s);
}
else {
for(int j=i; j<=n; j++) { //第x个位置可以选择(r[i-1]+1)~n的元素
path.push_back(j); //选择元素j
dfs(j+1, num+1);
path.pop_back(); //回溯:选择其他的元素
}
}
}
int main() {
while (scanf("%d", &n), n != 0) {
scanf("%d", &r);
dfs(1, 0); printf("\n");
}
return 0;
}
2、求解密码问题

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<functional>
using namespace std;
#define SWAP(a,b) {typeof(a) tmp=a; a=b; b=tmp;}
int n,len;
bool flag;
char str[13];
int num[13], x[5];
int fn(int a,int n){
int sum=a;
while(--n) sum=sum*a;
return sum;
}
void dfs(int i){
if(i==5){
if(fn(x[0],1)-fn(x[1],2)+fn(x[2],3)-fn(x[3],4)+fn(x[4],5)==n){
flag=true;
for(int j=0;j<5;j++) printf("%c",x[j]+'A'-1);
printf("\n");
}
return;
}
if(flag) return;
for(int j=i;j<len;j++){
SWAP(num[i],num[j]);
x[i]=num[i];
dfs(i+1);
SWAP(num[i],num[j]);
}
}
int main(){
while(scanf("%d",&n),n!=0){
scanf("%s",str);
flag=false;
len=strlen(str);
for(int i=0;i<len;i++) num[i]=str[i]-'A'+1;
sort(num,num+len,greater<int>());
dfs(0);
if(!flag) printf("no solution\n");
}
return 0;
}

浙公网安备 33010602011771号