C语言 · 排列数 · 排列式

蓝桥练习场上不断碰到类似的题,都是一个递归搜索的套路。

算法提高 排列数

时间限制:1.0s   内存限制:256.0MB

问题描述

  0、1、2三个数字的全排列有六种,按照字母序排列如下:
  012、021、102、120、201、210
  输入一个数n
  求0~9十个数的全排列中的第n个(第1个为0123456789)。

输入格式

  一行,包含一个整数n

输出格式

  一行,包含一组10个数字的全排列

样例输入

1

样例输出

0123456789

数据规模和约定

  0 < n <= 10!

作者注释:标准的递归搜索题,如今这是个套路。

 1 #include<stdio.h>
 2 #include<string.h>
 3 int n,sum=0;
 4 bool use[10];//用来标记数字i是否被用了,即是否已被放在了排列中
 5 int a[10];
 6 void dfs(int begin){
 7     if(begin==10){  //表示当前数组a中已有10个数字
 8         sum++;
 9         if(sum==n){
10             for(int i=0; i<10; i++)
11                 printf("%d",a[i]);
12         }
13     }
14     for(int i=0; i<=9; i++){//枚举数字0到数字9
15         if(!use[i]){
16             use[i]=true;
17             a[begin]=i;//数组第一个元素为0
18             dfs(begin+1);
19             use[i]=false;
20         }
21     }
22 }
23 int main(){
24     memset(use,false,sizeof(use));
25     scanf("%d",&n);
26     if(n==0){
27         return 0;
28     }
29     dfs(0);
30     return 0;
31 }  

算法提高 排列式

时间限制:1.0s   内存限制:256.0MB

问题描述

  7254是一个不寻常的数,因为它可以表示为7254 = 39 x 186,这个式子中1~9每个数字正好出现一次
  输出所有这样的不同的式子(乘数交换被认为是相同的式子)
  结果小的先输出;结果相同的,较小的乘数较小的先输出。

输出格式

  每一行输出一个式子,式子中的等号前后空格、乘号(用字母x代表)前后空格
  较小的乘数写在前面

样例输出

问题中的式子在结果中会出现一行如下:
7254 = 39 x 186

方法一:暴力枚举呗,注意判断条件。(运行超时)

 1 #include<stdio.h>
 2 void meiju(){//解题函数
 3     int count=0,m,n,x;
 4     int p,q;
 5     for(int a=1; a<10; a++)
 6         for(int b=1; b<10; b++)
 7             for(int c=1; c<10; c++)
 8                 for(int d=1; d<10; d++)
 9                     for(int e=1; e<10; e++)
10                         for(int f=1; f<10; f++)
11                             for(int g=1; g<10; g++)
12                                 for(int i=1; i<10; i++)
13                                     for(int j=1; j<10; j++){
14                                         //保证1-9只出现一次
15                                         if(a!=b&&a!=c&&a!=d&&a!=e&&a!=f&&a!=g&&a!=i&&a!=j&&b!=c&&b!=d&&b!=e&&b!=f&&b!=g&&b!=i&&b!=j&&c!=d&&c!=e&&c!=f&&c!=g&&c!=i&&c!=j&&d!=e&&d!=f&&d!=g&&d!=i&&d!=j&&e!=f&&e!=g&&e!=i&&e!=j&&f!=g&&f!=i&&f!=j&&g!=i&&g!=j&&i!=j){
16                                             m=a*1000+b*100+c*10+d;
17                                             n=e*10+f;
18                                             x=g*100+i*10+j;
19                                             p=e;
20                                             q=f*1000+g*100+i*10+j;
21                                             if (m==n*x){
22                                                 count++;
23                                                 printf("%d=%dx%d\n",m,n,x);
24                                             }
25                                             if(m==p*q){
26                                                 count++;
27                                                 printf("%d=%dx%d\n",m,p,q);
28                                             }
29                                         }
30                                     }
31     printf("共有%d种。",count);
32 }
33 int main(){
34     meiju();
35     return 0;
36 }

  方法二:递归搜索

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 int sum=0;
 4 bool use[10];
 5 int a[10];
 6 void dfs(int begin){
 7     if(begin==9){  //表示当前数组a中已有9个数字
 8         int num1=a[0]*1000+a[1]*100+a[2]*10+a[3];
 9         int num2=a[4]*10+a[5];
10         int num3=a[6]*100+a[7]*10+a[8];
11         int num4=a[4];
12         int num5=a[5]*1000+a[6]*100+a[7]*10+a[8];
13         if(num1==num2*num3){
14             printf("%d = %d x %d\n",num1,num2,num3);
15         }
16         if(num1==num4*num5){
17             printf("%d = %d x %d\n",num1,num4,num5);
18         }
19         return;
20     }
21     for(int i=1; i<=9; i++){//枚举数字1到数字9
22         if(!use[i]){
23             use[i]=true;
24             a[begin]=i;//数组第一个元素为0
25             dfs(begin+1);
26             use[i]=false;
27         }
28     }
29 }
30 int main(){
31     memset(use,false,sizeof(use));
32     dfs(0);//对数组a来讲,表示从第 1个位置开始搜索
33     return 0;
34 }  
时间: 2024-10-16 19:11:40

C语言 · 排列数 · 排列式的相关文章

C语言 &#183; 排列数

算法提高 排列数 时间限制:1.0s   内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排列中的第n个(第1个为0123456789). 输入格式 一行,包含一个整数n 输出格式 一行,包含一组10个数字的全排列 样例输入 1 样例输出 0123456789 数据规模和约定 0 < n <= 10! 1 #include<stdio.h> 2 #includ

SCU 4424(求子集排列数)

A - A Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice SCU 4424 Description Time Limit: 1000ms Description Given N distinct elements, how many permutations we can get from all the possible subset of the eleme

第k个排列数

变长编码,这里排列的序号是0到n!-1,假设求 1,2,3,4 的第15个排列数,15/(3!) = 2, 余数是3,第一个数是(1,2,3,4)中的第二个数 3 (这里0是开始位置),3/(2!) = 1, 余数是1,第二个数就是(1,2,4)中的第一个数 2,  1/(1!) = 1, 余数是0,第三个数(1,4)中的第1个数就是4, 最后一个数就是1.结果就是3,2,4,1 #include <cstdio>#include <cstring>#include <vec

如何直观地理解排列数和组合数

如果要问我高中时学文科有什么不好,我觉得,最不好的一点就是在你上概率论课时,你听着老师讲的内容一脸蒙蔽,而其他同学纷纷表示自己高中时就已经学过了.之前做题遇到排列数与组合数都是直接写A和C,并不进行计算,所以对于其公式也只是记住能用就好,但是今天闲着无聊,想试着推导一下排列数和组合数的公式,也为了能深入理解排列数和组合数的原理,所以就开始了天马行空的想象. 对于排列数,可以视为“分步解决”的问题,也就是说: 第一步,从n个某物中选取1个,有n种选择方法: 第二步,从剩下的n-1个某物中选取1个,

十三:全排列-区间数排列

问题:全排列-区间数排列题目描述对n和m之间的数进行全排列(包括n和m,且:0<n<m<30),并且输出所有的排列结果输入两个整数,分别为n和m输出n和m之间所有数的全排列结果样例输入5 7样例输出5 6 75 7 66 5 76 7 57 5 6 7 6 5 1 #include<stdio.h> 2 #include<string.h> 3 int n,m; 4 void fun(int b[],int k){ 5 int i,j; 6 int t; 7 if

46. Permutations 排列数

46. Permutations 题目 Given a collection of distinct numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解析 class Solution_46 { public: void help(int

一道笔试题-给定一个正整数序列,请尝试将它们重新排列使得排列的结果最大。

问题描述:给定一个正整数序列,请尝试将它们重新排列使得排列的结果最大,例如正整数序列为9,31,35,3,7则最大值为9735331. 思路分析:先将正整数序列转换为字符串数组,然后字符串数组进行排序,最后依次输出字符串数组即可.根据题目的要求,两个数字m和n排成的数字mn和nm,如果mn<nm,那么我们应该输出nm,也就是m应该排在n的后面,也就是m<n.反之,如果nm<mn,m排在n的前面,n<m.如果mn==mn,m等于n. 比较函数的定义是本解决方案的关键.这道题其实就是希

6439. 【GDOI2020模拟01.17】小 ω 数排列

题目描述 Description Input Output Sample Input Sample Input1 4 10 3 6 2 9 Sample Input2 8 35 3 7 1 5 10 2 11 6 Sample Output Sample Output1 6 [样例 1 解释] 共有 6 个排列符合条件,它们是 (1, 3, 2, 4),(2, 4, 1, 3),(3, 1, 2, 4),(3, 1, 4, 2),(4, 2, 1, 3),(4, 2, 3, 1). Sample

递归基础—组合数 / 排列数—输出的各种办法(dfs/递归/bfs)

B: 部分和问题***(注意部分和 ! = 任意子区间求和不一样) 描述   给你N个数,问你能不能从其中取出一些,让它们的和为K. 输入 第一行包括两个数,N,K,分别代表数字个数,以及和为K. 接下来N行,每行一个数字. 输出 如果能选出一些数和为K, 输出YE5,  否则,输出N0 样例 输入: 4 0 1 -1  2  3 输出: YE5 输入: 2 2 1 -3 输出: N0 本题求组合数和,注意pe之外,思维比较基础,办法很多,以下为利用dfs思想实现的一种办法 如果求组合数输出各种