zoukankan      html  css  js  c++  java
  • 全排列(防止重复)

    相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba

    思路:

    这道题的思路其实挺简单的,就是dfs去搜索就可以了。

    但是有一个问题就是 如何去防止重复呢?

    先想一下简化的问题吧,假如输入的字符串不重复,例如abcd,那么就是简单的dfs了,一个for循环加一个vis判断,如果判断可以,继续递归。

    当有重复的字符时候就比较麻烦了,比如aab,单纯的用递归会输出重复的。那么怎么加上限定条件呢。

    这里,我们让重复的这些字符只顺序输出一遍,这样就不会重复

    这是什么意思呢,比如说aabc,我们只允许第一个a访问后再访问第二个a,不允许访问第二个,再第一个

    再如,abacda,那三个a只能按顺序访问。

    原理是什么呢,用了点高中学的排列组合的知识,先排重复的,例如我们搞abacda这个例子, 先排三个a, 就是 aaa,那么剩下的就相当于直接插入到aaa中,那么如果我们aaa如果按多种顺序排,就会产生多种结果,所以只能按顺序访问。

    那么又如何用算法实现呢,直接加个if判断就行了,判断i之后的有没有访问过的且相等的。例如,aabc这个例子,我们第一轮选完之后,到了第二个a,然后进入递归,for循环又从0开始,到了第一个a,然后从这个之后去判断有没有访问过的a,结果判断有,违反了顺序,所以结束。

    这个题目的关键也就是排除重复的

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <stdlib.h>
     4 #include <string>
     5 #include <string.h>
     6 #include <set>
     7 #include <queue>
     8 #include <stdbool.h>
     9 
    10 #define LL long long
    11 #define inf 0x3f3f3f3f
    12 using namespace std;
    13 const int MAXN=1e3+5;
    14 
    15 char str[MAXN],buff[MAXN];
    16 int vis[MAXN],cnt,len;
    17 
    18 void dfs(int num)
    19 {
    20     if (num == len)
    21     {
    22         cnt++;
    23         printf("%s
    ",buff);
    24         return ;
    25     }
    26     for (int i=0;i<len;i++)
    27     {
    28         if (!vis[i])
    29         {
    30             int j;
    31             for (j=i+1;j<len;j++)
    32             {
    33                 if (str[i]==str[j] && vis[j])
    34                 {
    35                     break;
    36                 }
    37             }
    38             if (j == len)
    39             {
    40                 vis[i] = 1;
    41                 buff[num] = str[i];
    42                 dfs(num+1);
    43                 vis[i] = 0;
    44             }
    45         }
    46     }
    47 
    48 }
    49 
    50 
    51 
    52 int main()
    53 {
    54 #ifndef ONLINE_JUDGE
    55     freopen("../in.txt","r",stdin);
    56 #endif
    57     while (~scanf("%s",str))
    58     {
    59         len = strlen(str);
    60         sort(str,str+len);
    61         cnt = 0;
    62         memset(vis,0, sizeof(vis));
    63         dfs(0);
    64         printf("%d
    ",cnt);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    利用表格分页显示数据的js组件datatable的使用
    css和javascript代码写在页面中的位置说明
    jqueryui组件progressbar进度条和日期组件datepickers的简单使用
    漏洞扫描工具Nessu的安装和简单使用
    jqueryui插件slider的简单使用
    html常用标签表单和表格等及css的简单入门
    通过flask实现web页面简单的增删改查bootstrap美化版
    jquery简单使用入门
    bootstrap简单使用布局、栅格系统、modal标签页等常用组件入门
    Centos7.3_x86_64通过systemctl控制tomcat8.0.46启动和停止
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11218570.html
Copyright © 2011-2022 走看看