dsf 实现各种排序

dfs入门级(模板)

dfs基本模型

void dfs(int step)
{
    判断边界
    尝试每一种可能for(int i=1;i<=n;i++)
    {
        继续下一步  dfs(step+1)
    }
    返回
}

全排列

#include<bits/stdc++.h>
using namespace std;

const int N=10;
int n;
int path[N];  //记录所有的搜索路径 
bool st[N];   //记录这些点是否被用过,用过true,没用过为false 

void dfs(int x)   //从第x层开始 
{
	if(x==n) //从0开始作为第一层,当搜索完最后一层,就输出这条路径并结束递归 
	{
		for(int i=0;i<n;i++) printf("%d ",path[i]);
		printf("\n"); 
	//	return ;
	}
	for(int i=1;i<=n;i++)  从1开始 (题意)为当前位置枚举可用数字 
	{
		if(st[i]==false)  //找到一个未被用过的数 
		{ 
			path[x]=i;  为第x层赋值,path[x]赋值 
			st[i]=true;
			dfs(x+1);     //放下一个盒子(为下一个位置选数字)
			//下一层递归结束,恢复现场 
			st[i]=false;  //恢复现场 
		}
	}
}

int main()
{
	cin>>n;
	
	dfs(0);
	
	return 0;
}

排列组合(字母)

任务描述

1.设计算法从前m个大写字母(m≤26)种取出n个字母的所有排列(组合),并编程实现

输入格式

输入M N
1<=M=26, N<=M

输出格式

按字典序输出排列
注意:行末不输出多余空格

Sample Input

4 2

Sample Output

A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C

#include<stdio.h>
//#include<bits/stdc++.h>
//using namespace std;

int m,n;
char a[27],path[27];
bool st[27];

void dfs(int x)
{
	if(x==n)
	{
		for(int i=0;i<n;i++)
		{
			if(i==n-1)
			printf("%c\n",path[i]);
			else
			printf("%c",path[i]);
		}
		return;
	}
	else
	{
		for(int i=0;i<m;i++)
		{
			if(st[i]==false)
			{
				path[x]=a[i];
				st[i]=true;
				dfs(x+1);
				st[i]=false;
			}
		}
		
	}
}

int main()
{
	scanf("%d %d",&m,&n);
	//赋值 
	for(int i=0;i<m;i++)
	{
		a[i]='A'+i;
	}
	dfs(0);
	return 0;
}

组合

给定n,k,输出1~n中所有可能的k个数的组合

#include<bits/stdc++.h>
using namespace std;
int n,k;
vector<int> path;

void dfs(int x)
{
	if(path.size()==k)
	{
		for(int i=0;i<path.size();i++) printf("%d",path[i]);
		printf("\n");
	return ;
	}
	else
	{
		for(int i=x;i<=n;i++)  //index每次从不同的值开始,x相当于index 
		{
			path.push_back(i);
			dfs(i+1);
			path.pop_back();
		}
	}
}

int main()
{
	
	scanf("%d %d",&n,&k);
	
	dfs(1);
	
	return 0;
}

有重复元素的排列问题

输入描述

第1行是元素个数n,1<=n<=500。接下来的1行是待排列的n个元素,元素中间不要加空格。

输出格式

程序运行结束时,将计算输出n个元素的所有不同排列。最后1行中的数是排列总数。

测试说明

平台会对你编写的代码进行测试:

测试输入:
4
aacc

预期输出:
aacc
acac
acca
caac
caca
ccaa
6

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int n, i, sum = 0;
 char a[1111];

void swap(char &a, char &b) {
    char temp = a;
    a = b;
    b = temp;
}
 
int findsame(char a[], int k, int m) {
    for(int i = k; i < m; i++) {
        if(a[i] == a[m]) return 1;
    }
    return 0;
}
 
void sort(int k) {
    if(k == n) {
    	 for(int i =0; i <n; i++) {
            printf("%c",a[i]);
        }
        printf("\n");
        sum++;
    }else{
        for(int i = k; i <n; i++) 
		{
            if (findsame(a,k,i) == 1)  //a[k]到a[i-1]之间是否存在与元素a[i]相同 
                continue;
            swap(a[k], a[i]);
            sort(k+ 1);
            swap(a[k], a[i]);
        }
    }
}
 
int main()
{
    
    scanf("%d",&n);
    scanf("%s",a);
    sort(0);
    printf("%d",sum);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值