【第十五届蓝桥杯备赛(bushi,写文凑个数)】蓝桥OJ---排列序数

一、题目

1、原题链接

排列序数

2、题目描述

如果用 a b c d 这 4 个字母组成一个串,有 4!=24 种,如果把它们排个序,每个串都对应一个序号:

abcd 0

abdc 1

acbd 2

acdb 3

adbc 4

adcb 5

bacd 6

badc 7

bcad 8

bcda 9

bdac 10

bdca 11

cabd 12

cadb 13

cbad 14

cbda 15

cdab 16

cdba 17

⋯ ⋯
现在有不多于 10 个两两不同的小写字母,给出它们组成的串,你能求出该串在所有排列中的序号吗?
输入描述
输入一行,一个串。

输出描述

输出一行,一个整数,表示该串在其字母所有排列生成的串中的序号。注意:最小的序号是 0。

输入输出样例

输入

bdca

输出

11

二、解题报告

1、思路分析

(1)DFS搜索即可,和全排列数思路一样。
(2)至于序号,与我们搜索到的方案数顺序正好相同,直接将每次搜索到的方案数编号,当时第一思路是将每种方案和其编号记录到哈希表中,之后再进行查找,但是有几个数据超时了(时间复杂度最坏10*10!,超过计算机1s计算量)。可以直接搜到输入的方案直接输出,结束程序即可。

2、时间复杂度

时间复杂度O(n*n!)

3、代码详解

#include <iostream>
#include <string>
using namespace std;
const int N=15;
bool st[N];
string s;
int idx,len;
//DFS搜索,和全排列数的搜索方式相同,只不过参数成了字符串
void dfs(int u,string path){
  //如果找到一组方案
  if(u==len){
     //判断是否和输入的字符串相同
     if(path==s){
         cout<<idx;   //如果相同,直接输出其编号
         exit(0);    //结束程序
     }
     idx++;        
     return ;
  }
  //搜索,填充每位上的字符
  for(int i=0;i<len;i++){
      if(!st[i]){    //如果该位的数字没有被用过
         char in=char('a'+i),tmp=path[u];
         path[u]=in;     //将该位置填上数
         st[i]=true;     //标记为该字母以用过
         dfs(u+1,path);   //搜索下一个位置
         st[i]=false;    //回溯
         path[u]=tmp;    //回溯
    }
  }
}
int main()
{  cin>>s;
   len=s.size();    //记录字符串长度
   dfs(0,s);   //搜索每种该长度字符串的组合方式
  return 0;
}

三、知识风暴

DFS

  • 参考这里
  • exit(0):功能—正常运行程序并退出程序,可以用于在非主函数中直接结束程序。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马看到什么是人决定的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值