Ka的回溯编程练习 Part6.5|详解|有重复元素的排列问题

#include <stdio.h>
#define br printf("\n");
int ans=0;
char el[502];
int confirm(int i,int k) //往回比较,如果元素有相同跳过此情况
{
    if(i>k)
    {
        while(i>k)
        {
            if(el[i]==el[k]) return 0;
            k++;
        }
    }
    return 1;
}
void op(int n)
{
    ans++;
    int j;
    for(j=0;j<=n;j++) printf("%c",el[j]);
    br
}
void perm(int n,int k)
//n代表当前距离分配结束的个数(数组模式,-1) k代表当前元素的位置
{
    int i,r;
     if(n==k) op(n);  //如果两个数已经达到相等 输出
    else for(i=k;i<=n;i++)  //从当前数组元素开始一直到末尾,逐个进行交换
        if(confirm(i,k))//根据返回结果进行交换
        {
            r=el[i];el[i]=el[k];el[k]=r;
            perm(n,k+1); //推进k的一位
             r=el[i];el[i]=el[k];el[k]=r;
        }
}
int main()
{
    int n,i;
    scanf("%d",&n);
    getchar();
    for(i=0;i<n;i++)
        scanf("%c",&el[i]);   //以上是普通的输入环节
    perm(n-1,0);
    printf("%d",ans);
    return 0;
}

原谅我的恶趣味哈哈哈。

整个思路是这样的:

a a c c

0 1 2 3

首先和自己交换一次

a a c c

a a c c 后方字母乱序

然后递归下去,不停地把往后每个字符都代到当前位置寻找下一步情况。

c a a c

如果不是在和自己交换,那么检测一下是否在之前交换过同样的元素。比如:

a b c d e f e h

a b c e d f e h 后方字母乱序

如果下一次和下一个e交换,那么效果和第一个e相同,都是后面顺序不管,abce往下找。

a b c d e f e h

a b c e e f d h

检测要从前往后找,这样能找到第一位的

a b c d e f e h

      k     i

a b c d e f e h

        k   i 相等,跳过此情况

慢慢体会吧。应该很清楚了

时间: 2024-10-10 15:21:07

Ka的回溯编程练习 Part6.5|详解|有重复元素的排列问题的相关文章

Ka的回溯编程练习 Part6|有重复元素的排列问题

第一个问题: 有红球4个,白球3个,黄球3个,将它们排成一排共有多少种排法 #include <stdio.h> int BallsIUsed[201]; int BallsIHave[201]={0}; int total=0; int k; void op() { int i; total++; printf("%d:",total); for(i=1;i<=k;i++) { printf("%c",BallsIUsed[i]); } prin

Linux 程序设计学习笔记----终端及串口编程基础之概念详解

转载请注明出处,谢谢! linux下的终端及串口的相关概念有: tty,控制台,虚拟终端,串口,console(控制台终端)详解 部分内容整理于网络. 终端/控制台 终端和控制台都不是个人电脑的概念,而是多人共用的小型中型大型计算机上的概念. 1.终端 一台主机,连很多终端,终端为主机提供了人机接口,每个人都通过终端使用主机的资源. 终端有字符哑终端和图形终端两种. 控制台是另一种人机接口, 不通过终端与主机相连, 而是通过显示卡-显示器和键盘接口分别与主机相连, 这是人控制主机的第一人机接口.

网络编程socket基本API详解(转)

网络编程socket基本API详解 socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件. socket 类型 常见的socket有3种类

iOS开发——网络编程Swift篇&amp;Alamofire详解

Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AFNetworking非常稳定,在Mac OSX与iOS中也能像其他Objective-C代码一样用Swift编写.不过Alamofire更适合Swift语言风格习惯(Alamofire与AFNetworking可以共存一个项目中,互不影响). Alamofire 取名来源于Alamo Fire fl

Java并发编程之---Lock框架详解

Java 并发开发:Lock 框架详解 摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等.Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题.本文以synchronized与Lock的对比为切入点,对Java中的Lock框架的枝干部分进行了详细介绍,最后给出了锁的一些相关概念. 一

面向对象编程(十六)——内部类详解

一.内部类(innerclasses) 一般情况,我们把类定义成独立的单元.有些情况下,我们把一个类放在另一个类的内部定义,称为内部类. 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类. 1. 内部类的作用 内部类提供了更好的封装,只能让外部类直接访问,不允许同一个包中的其他类直接访问. 内部类可以直接访问外部类的私用属性.内部类被当成其外部类的成员.但是外部类不能访问内部类的

网络编程Socket之RST详解

产生RST的三个条件: 1. 目的地为某端口的SYN到达,然而该端口上没有正在监听的服务器: 2. TCP想取消一个已有的连接: 3. TCP接收到一个根本不存在的连接上的分节: 现在模拟上面的三种情况: client: struct sockaddr_in serverAdd; bzero(&serverAdd, sizeof(serverAdd)); serverAdd.sin_family = AF_INET; serverAdd.sin_addr.s_addr = inet_addr(S

.NET中的异步编程,高并发处理详解地址

异步变成详解:https://www.cnblogs.com/mingjiatang/p/5267391.html 处理高并发:https://blog.csdn.net/andong154564667/article/details/82153104 原文地址:https://www.cnblogs.com/yjm8023/p/10912655.html

Ka的回溯编程练习 Part2|八皇后问题

1 #include <stdio.h> 2 int AChessBlockRecorder[10]={0}/*下标层数,内容竖行*/,ThisIsMyPlace[10]={0};/*占领*/ 3 int TheTalentOfTheQueen1[25]={0}; //前一个维度代表主对角线特性,相减同 4 int TheTalentOfTheQueen2[25]={0}; 5 int total=0; 6 void output() 7 { 8 total++; 9 printf("