题目链接:点击打开链接
擅长排列的小明
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
小明十分聪明,而且十分擅长排列计算。比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他,在这5个数字中选出几个数字让他继续全排列,那么你就错了,他同样的很擅长。现在需要你写一个程序来验证擅长排列的小明到底对不对。
-
输入
-
第一行输入整数N(1<N<10)表示多少组测试数据,
每组测试数据第一行两个整数 n m (1<n<9,0<m<=n)
输出
- 在1-n中选取m个字符进行全排列,按字典序全部输出,每种排列占一行,每组数据间不需分界。如样例 样例输入
-
2 3 1 4 2
样例输出
-
1 2 3 12 13 14 21 23 24 31 32 34 41 42 43
来源
- [hzyqazasdf]原创 上传者
- hzyqazasdf
方法:深搜
-
第一行输入整数N(1<N<10)表示多少组测试数据,
#include<stdio.h>
int a[10]={0,1,2,3,4,5,6,7,8,9},m,n,book[10],ans;
void dfs(int x,int y)
{
if(y==n)
{
printf("%d\n",ans);
return;
}
y++;
for(int i=1;i<=m;i++)
{
if(x==i)
continue;
if(book[i]==0)
{
book[i]=1;
ans=ans*10+a[i];
dfs(i,y);
book[i]=0;
ans/=10;
}
}
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
book[i]=1;
ans=i;
dfs(i,1);
book[i]=0;
ans=0;
}
}
}
//代码二
#include<stdio.h>
#include<string.h>
int m,n,a[10],vis[10];
void dfs(int x)
{
if(x==n)
{
for(int i=0;i<n;i++)
printf("%d",a[i]);
printf("\n");
return;
}
for(int i=1;i<=m;i++)
{
if(vis[i]==0)
{
a[x]=i;
vis[i]=1;
dfs(x+1);
vis[i]=0;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
if(vis[i]==0)
{
a[0]=i;
vis[i]=1;
dfs(1);
vis[i]=0;
}
}
}
}
方法二:
先来介绍两个计算全排列的函数:next_permutation(),prev_permutation(),具体用法看代码吧(c++的函数总是那么地好用)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int a[]= {1,2,3};
do
{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (next_permutation(a,a+3));//a+3是数组的大小
cout<<endl;
a[0]=3,a[1]=2,a[2]=1;
do
{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (prev_permutation(a,a+3));
return 0;
}
再来看看如何用全排列的函数解决这个问题
#include <cstdio>
#include <cstring>
#include <algorithm>
char a[10]={'1','2','3','4','5','6','7','8','9','\0'};//给定一个大小顺序排号的数组
using namespace std;
int main()
{
int t,n,m;
char b[10],c[10];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
strcpy(b,a);//全排列是按字典序开始的,所以第一组数据是从小到大的,直接复制;
b[m]='\0';//复制前面m个
printf("%s\n",b);
while(next_permutation(a,a+n))//给数组进行全排列
{
strcpy(c,a);
c[m]='\0';
if(strcmp(b,c))//判断b,c数组是否相等
{
strcpy(b,c);//依次把全排列后面的顺序输出
b[m]='\0';
printf("%s\n",b);
}
}
}
return 0;
}
stl还没开始学,先结仇一下吧,以后学起来也许会快一点
