HDOJ 1716 排列2(next_permutation函数)
Problem Description
Ray又对数字的列产生了兴趣:
现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。
Input
每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。
Output
对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔。
每组输出数据间空一行,最后一组数据后面没有空行。
Sample Input
1 2 3 4
1 1 2 3
0 1 2 3
0 0 0 0
Sample Output
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321
1123 1132 1213 1231 1312 1321
2113 2131 2311
3112 3121 3211
1023 1032 1203 1230 1302 1320
2013 2031 2103 2130 2301 2310
3012 3021 3102 3120 3201 3210
这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件
下面是以前的笔记 与之完全相反的函数还有prev_permutation
(1) int 类型的next_permutation
int main()
{
int a[3];
a[0]=1;a[1]=2;a[2]=3;
do
{
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;//输入a[0],a[1],a[2];
} while (next_permutation(a,a+3)); //参数3指的是要进行排列的长度
//如果存在a之后的排列,就返回true。如果a是最后一个排列没有后继,返回false,每执行一次,a就变成它的后继
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成 while(next_permutation(a,a+2));
则输出:
1 2 3
2 1
只对前两个元素进行字典排序
显然,如果改成 while(next_permutation(a,a+1)); 则只输出:1 2 3
若排列本来就是最大的了没有后继,
则next_permutation执行后,会对排列进行字典升序排序,相当于循环
int list[3]={3,2,1};
next_permutation(list,list+3);
cout<<list[0]<<" "<<list[1]<<" "<<list[2]<<endl;
//输出: 1 2 3
例题:
Problem B
Ray又对数字的列产生了兴趣:
现有四张卡片,用这四张卡片能排列出很多不同的4位数,
要求按从小到大的顺序输出这些4位数。
Input
每组数据占一行,代表四张卡片上的数字(0<=数字<=9),
如果四张卡片都是0,则输入结束。
Output
对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,
千位数字相同的在同一行,同一行中每个四位数间用空格分隔。
每组输出数据间空一行,最后一组数据后面没有空行。
Sample Input
1 2 3 4
1 1 2 3
0 1 2 3
0 0 0 0
Sample Output
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321
1123 1132 1213 1231 1312 1321
2113 2131 2311
3112 3121 3211
1023 1032 1203 1230 1302 1320
2013 2031 2103 2130 2301 2310
3012 3021 3102 3120 3201 3210
#include < iostream >
#include < stdio.h >
#include < algorithm>
#include < string.h>
using namespace std;
int main()
{
int a[5],i,j,k,m=0;
while(~scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]))
{
if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0)
return 0;
if(m)
printf("\n");
m=1;
k=1;int h;
do
{
if(a[1]==0)
continue;
if(k==1)
{
printf("%d%d%d%d",a[1],a[2],a[3],a[4]);
k=0;
}
else
{
if(h==a[1])
printf(" %d%d%d%d",a[1],a[2],a[3],a[4]);
else
printf("\n%d%d%d%d",a[1],a[2],a[3],a[4]);
}
h=a[1];
}
while(next_permutation(a+1,a+5));
printf("\n");
}
return 0;
}
算法描述:
1、从尾部开始往前寻找 两个相邻 的元素
第1个元素i,第2个元素j(从前往后数的),且i<j
2、再从尾往前找第一个大于i的元素k。将i、k 对调
3、[j,last)范围的元素置逆( 颠倒排列 )
这个题目用递归也可以做:
#include < stdio.h>
#include < string.h>
#include < stdlib.h>
int a[6],vis[5],t,sol[5],last;
void dfs(int c)
{
if(c==5)
{
if(sol[1]==0)
return; //千位是0的不符合
if(t!=0 && sol[1]==last)
printf(" "); //一行的最后一个数后面不能输出空格
if(t!=0 && sol[1]!=last)
{
printf("\n"); //千位不同则换行
}
last=sol[1]; //记录上一个的千位
int j=1;
for(j ; j < = 4 ; j++)
{
printf("%d",sol[j]);
}
t++;
}
int i;
for(i = 1 ; i <= 4 ; i++)
{
if(vis[i]==0)
{
vis[i]=1;
sol[c]=a[i];
dfs(c+1);
vis[i]=0;
while(a[i]==a[i+1]) //关键: 去重复
i++; //因为题目的输入是从小到大(否则先排序),所以如果在一轮排列结束后
} //如果后一个将要被选的数与上一轮这个下标的数相同,则跳过
} //比如1 1 1 2,第一轮1 1 1 2,返回上一次dfs后sol[3]=2,sol[4]=1
} //返回到c=2,此时a[2]==a[3]=1,若再选1则为1 1 1 2,跳过则为1 2 1 1
int main()
{
int i,T=0;
while(scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]))
{
if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0) break;
if(T!=0) printf("\n");
T=1;
memset(vis,0,sizeof(vis));
t=0;
dfs(1);
printf("\n");
}
return 0;
}
HDOJ 1716 排列2(next_permutation函数)的更多相关文章
- HDOJ 1716 排列2 next_permutation函数
Problem Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡 ...
- hdu 1027 Ignatius and the Princess II(产生第m大的排列,next_permutation函数)
题意:产生第m大的排列 思路:使用 next_permutation函数(头文件algorithm) #include<iostream> #include<stdio.h> ...
- c++中STL中的next_permutation函数基本用法
对于next_permutation函数是针对于排列组合问题的库函数,它的排序方式是按照字典的方式排列的·: 如以下代码对于next_permutation函数的初步解释: #include<c ...
- 全排列函数 nyoj 366(next_permutation()函数)
C++ STL中提供了std::next_permutation与std::prev_permutation可以获取数字或者是字符的全排列,其中std::next_permutation提供升序.st ...
- POJ-1256 next_permutation函数应用
字典序列: 在字典序中蕴含着一个点,就是大小的问题,谁先出现,谁后出现的问题.譬如a<b<c,出现顺序就是a,b,c. 本题中字符集是所有大小写字母,而题目中规定的谁大谁小已经不是按asc ...
- hdu 1716 排列2(DFS搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1716 排列2 Time Limit: 1000/1000 MS (Java/Others) Me ...
- next_permutation()函数 和 prev_permutation() 按字典序求全排列
next_permutation功能: 求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件<algorithm> 与之完全相反的函数还有prev_permutation 这个 ...
- 【HDOJ】1716 排列2
STL. /* 1716 */ #include <iostream> #include <algorithm> #include <cstdio> #includ ...
- 关于全排列 next_permutation() 函数的用法
这是一个c++函数,包含在头文件<algorithm>里面,下面是基本格式. 1 int a[]; 2 do{ 3 4 }while(next_permutation(a,a+n)); 下 ...
随机推荐
- eclipse EE neon创建dynamic web project时,卡在installing dynamic web module facet,解决办法
我们在用eclipse EE neon创建dynamic web project时,如果你发现底部状态栏一直卡在installing dynamic web module facet,永远到不了100 ...
- Codeforces 553C Love Triangles(图论)
Solution: 比较好的图论的题. 要做这一题,首先要分析love关系和hate关系中,love关系具有传递性.更关键的一点,hate关系是不能成奇环的. 看到没有奇环很自然想到二分图的特性. 那 ...
- Linux 权限基础说明
1 权限位说明 Linux文件或目录的权限位是由个9个权限位来控制的,每三位为一组,它们分别是文件属主(owner/user)读.写.执行,用户组(Group)的读.写.执行以及(Other)其他 ...
- js 组件的写法
var Test1 = function(){ var name = ""; this.setName = function(username){ name = username; ...
- pushState与replaceState区别
history.pushState(state, title, url) 将当前URL和history.state加入到history中,并用新的state和URL替换当前.不会造成页面刷新. sta ...
- 使用Node.js作为后台进行爬虫
看了一遍又一遍Node.js但是没过多久就又忘了,总想找点东西来练练手,就发现B站首页搜索框旁边的GIF图特别有意思,想着是不是可以写一个小Node.js项目把这些图全部扒下来,于是带着复习.预习与探 ...
- 一次 php nusoap 调试过程
今天跟同事调用一个数据api ,用soap方式调用.本以为很简单的事情,却弄到了晚上. 因为有过调试经验,直接按照以往的过程直接部署,结果是错误. 1. 以为是调用方式错了,问了一下对接的同事,没问题 ...
- C# 仿迅雷风格选项卡
private void listView1_SelectedIndexChanged(object sender, EventArgs e) { listView1.FullRowSelect = ...
- Python之简单的SMTP发送邮件详细教程附代码
简介 Python发送邮件的教程本人在网站搜索的时候搜索出来了一大堆,但是都是说了一大堆原理然后就推出了实现代码,我测试用给出的代码进行发送邮件时都不成功,后面找了很久才找到原因,这都是没有一个详 ...
- ios8新特性widget开发-b
os8发布已经有一段时间了,伴随着ios8同时也出现了许多新的特性,ios系统将会越来越开放,这是好事.其中一个新特性就是在下拉通知栏里加入了个性的widget,开发者可以自己定义widget的样式内 ...