当前位置:网站首页>详解全排列问题(不同的解法的不同输出结果)
详解全排列问题(不同的解法的不同输出结果)
2022-07-19 05:04:00 【孤独时代的c0re】
目录
前言
QWQ昨天的PTA里面老师布置的实验题,原来的时候一晚上一章不在话下,当我正想今天也瞬间把老师布置的小实验题做完然后来写写博客的时候,**(此处为会被和谐的话),一晚上,这个全排列问题就是输出不出来了,我想这小小全排列问题能有多大坑???一直都是部分错误,我就死磕,不看C站,我感觉老资递归学的还可以啊,这小小代码能难得到我???于是,一晚上过去了,自己写了两个全排列算法,全是部分错误,我才发现,事情并不是像想象的那样简单。全排列中的对于输出结果的排序是有要求的而不是你输出了,就可以。。。于是在问了大神正确答案后,我恍然大悟!!!
我是菜鸡:[
题目介绍
输入样例:
3
1 2 3
输出样例:
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
在开始之前大家可以先自己写一下看一下能不能自己写出来~注意输出的格式哦!
引入:
这个问题,不用说一看就是一个递归或者递推的问题,鄙人不才,只会递归。。所以说怎么进行递归呢??
首先你要看看这个排序是你懂吧!你看那个3,1,2和3,2,1就是先1,2后2,1这种,我当时做了一晚上,**就有一些测试案例不对!!!很烦!
这个题需要用到回溯法
理论存在,实践开始!
解决方案:
错误方案1:
#include <stdio.h>
void swap(int *q,int *p)
//两个数交换函数,注意函数的形参要用指针变量,这样才能是目标数组中的数据改变;
{
int t;
t = *q; //将q指针指向的数据赋给t;
*q = *p;
*p = t; //将t中的数据赋给p指针指向的位置空间;
}
void f(int a[],int k,int m)
//定义一个求全排列的函数,在下面递归中就将这个函数作为已知完整的函数使用;
{
int i;
if(k==m) //递归结束的标志;
{
for(i=0; i<=m; i++)
{
if(i==0)
printf("%d",a[i]);
else printf(",%d",a[i]);
}
printf("\n");
}
else
{
for(i=k; i<=m; i++)
{
swap(&a[k],&a[i]);
f(a,k+1,m);
swap(&a[k],&a[i]);
}
}
}
int main ()
{
int array[11],i,t,n;
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d",&array[i]);
}
f(array,0,n-1);
}
}
return 0;
}
这样的话后面那两个案例会先输出3,2,1再输出3,1,2不全对!
错误方案2:
#include<stdio.h>
int a[10],c[10],n,d[10];//c数组对出现过的数字进行标记,d数组为记录答案的数组
void dfs(int i);
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
c[i]=0;//对计数数组进行初始化
}
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
dfs(0);
}
void dfs(int x)
{
if(x==n)
{
for(int v=0;v<n;v++)
{
printf("%d ",d[v]);
}
printf("\n");
return ;
}
else
{
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
d[x]=a[i];
//printf("%d ",a[i]);
c[i]=1;
dfs(x+1);
c[i]=0;
}
}
}
}
这样只能输入一个数,而且不能案例全对(别问,我本来想偷鸡来)
正确方案1:
递归回溯法:(代码后有注释哦!!!)
#include<stdio.h>
void f(int *a, int p, int q)
{
int j,i;//循环变量
if(q == p)// 递归截止条件:尾变量=头变量,截止后输出。
{
for(i = 0 ; i <= q ; i++)
{
if(i == q)
{
printf("%d\n",a[i]);
}// 打印最后一个
else printf("%d,",a[i]);// 打印前面的
}
}
else//进行递归
{
for(i = p ; i <= q ; i ++) //遍历数组每一个
{
if(i == 0)
{
f(a, p + 1, q);//对第二个数以及以后的数进行全排列
}//当p是数组的第一个数时
else
{
int t = a[i];//暂时存一下
for(j = i - 1 ; j >= p ; j --)
{
a[j + 1] = a[j];
}
a[p] = t ;//把第i个数放到最前面
f(a, p + 1 , q);//使用递归求后面的全排列
t = a[p];
for(j = p + 1; j <= i ; j ++)
{
a[j - 1] = a[j];
}
a[i] = t;// 回溯(把第一个数放到末尾)
}
}
}
}
int main()
{
int n ;
scanf("%d",&n);
int a[100] ;
int i;
for(i = 0 ; i < n ; i ++)
{
scanf("%d",&a[i]);
}
f(a, 0, n - 1);//进行全排列
}
总结:
讲一下这个是怎么递归的吧!你看这个!如果输入123的话,他会这样进行!
绿色的是进行回溯的先后
红色的是打印数据的前后
嘿嘿,好好看看应该能看懂吧,很简单的递归回溯问题!
就是把每一个数都移到首位然后再移回去进行回溯!把每个数移到首位就可以实现全排列!
有点不详细哈。。应该能看懂吧,等我考完试再补充补充(画大饼)
Love is worth years.
热爱可抵岁月漫长。
边栏推荐
- yolov3的GUI界面(简易,图片检测)
- 用C实现三种版本的通讯录
- [signal conditioning] sharing practical experience of building CE amplifier with "crystal triode"
- STM32-定时器
- Yolov5 apple banana detection
- yolov3训练自己的数据集
- STM32-串口
- Sword finger offer serialized binary tree
- 分享本周所学——Transformer模型详解
- Esp8266 -- temperature and humidity monitoring code dht-11 (web page display)
猜你喜欢
Mysql千万级别水平分表优化
Yolov5 apple banana detection
pytorch yolo4训练任意训练集
ZABBIX agent adds a user-defined monitoring item -- Ping to destination IP link monitoring
华录杯-江苏违法广告检测-冠军总结
pytorch 目标检测数据处理比赛使用
pytorch 目标检测数据增强cutmix和mixup混合
【YOLOv5实现玩手机检测】
Sword finger offer serialized binary tree
Based on STM32F103, play songs with buzzer
随机推荐
函数指针
pytorch 华为云杯垃圾分类总结(目标检测)
编程实现猜密码游戏
STM32-使用定时器做延时函数时遇到的坑
c语言-链表二叉树-创建-遍历-求高度等复试常见问题
pytorch 使用免费gpu测试训练(aistudio)yolov4为例
Basic page status code
idea svn主干合并分支版本Missing ranges异常Error:svn: E195016
Yolov5 realizes smoking behavior detection
Upgrade single instance Mongo to replica set
菜鸟教你修U盘
There is a problem that the picture cannot be found after the jar package is printed on the swing form
Problème de partition des entiers
Sword finger offer serialized binary tree
Pytorch uses free GPU test training (aistudio) yolov4 as an example
Based on STM32F103, play songs with buzzer
STM32-点灯程序
整數的分劃問題
Pytorch target detection coco API explanation data generation
pytorch yolo4训练任意训练集