全排列
问题描述:将n个互不相同的数全排列,即1,2,······n
方法:dfs
算法思路:
dfs(从第一层开始){if(递归结束条件){遍历a[i]}打印换行for(循环n个位数) {if(当前数字没用过){第k层(第k个位置)填数字i标记置为1进入下一层标记重新置0}}
}
代码:
#include<stdio.h>int n,flag[100],a[100];
void dfs(int k){if(k==n+1){ //递归结束条件,当到达第n+1层,代表第n层已经填完for(int i=1;i<=n;i++){printf("%d ",a[i]);}printf("\n");}for(int i=1;i<=n;i++){ //n个数字 if(flag[i]==0){ //当前数字没用过才可以排列a[k]=i; //第k层(第k个位置)填数字iflag[i]=1; //该数已经用过,置为1dfs(k+1); //填下一层(下一个位置)flag[i]=0; //递归回来的时候需要重新置为0 }}
}
int main()
{scanf("%d",&n);dfs(1); //从第一层(第一个位置)开始排列 return 0;
}
n个数选m个数全排列
#include<stdio.h>int n,m,flag[100],a[100];
void dfs(int k){if(k==m+1){ //递归结束条件,当到达第n+1层,代表第n层已经填完for(int i=1;i<=m;i++){printf("%d ",a[i]);}printf("\n");}for(int i=1;i<=n;i++){ //n个数字if(flag[i]==0){ //当前数字没用过才可以排列a[k]=i; //第k层(第k个位置)填数字iflag[i]=1; //该数已经用过,置为1dfs(k+1); //填下一层(下一个位置)flag[i]=0; //递归回来的时候需要重新置为0}}
}
int main()
{scanf("%d %d",&n,&m);dfs(1); //从第一层(第一个位置)开始排列return 0;
}
n个不同的元素,任取m个数进行组合。(组合无序)
#include<stdio.h>int n,m;
int a[1000];void dfs(int k){if(k==m+1){ //递归结束条件,当到达第m+1层,代表第m层已经填完for(int i=1;i<=m;i++){printf("%d ",a[i]);}printf("\n");}//当前位置数值比前一个数至少大1,a[k]代表当前位置上的值,它的范围是[a[k-1]+1,n]for(int i=a[k-1]+1;i<=n;i++){a[k]=i; //第k层(第k个位置)填数字idfs(k+1); //填下一层(下一个位置)}
}int main(){scanf("%d %d",&n,&m);dfs(1); //从第一层(第一个位置)开始排列return 0;
}
素数环
题目:
素数环:把从 1 到 n 这 n 个数摆成一个环,要求相邻两个数的和是一个素数,编
程求出所有解法。
#include<stdio.h>
#include<math.h>int n=6;
int flag[100],a[100];
int exist = 0;int prime(int n){for(int i=2;i<=sqrt(n);i++){if(n%i==0){return 0;}}return 1;
}void dfs(int k){if(k==n+1 && prime(a[1]+a[k])){for(int j=1;j<=n;j++){printf("%d",a[j]);exist = 1;}printf("\n");}else{for(int i=1;i<=n;i++){if(flag[i]==0 && (k==1 || prime(i+a[k-1]))){a[k]=i;flag[i]=1;dfs(k+1);flag[i]=0;}}}
}int main(){dfs(1);if(flag == 0)printf("无解");return 0;
}
以上属个人见解。
❤️希望对您有帮助,您的支持是我创作最大的动力!