HDU-1716()(全排列+重集排列)
排列2
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6418 Accepted Submission(s): 2475
现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。
每组输出数据间空一行,最后一组数据后面没有空行。
该题格式有点坑,在每个排列之间有空格,每行的第一个排列前面不能有空格,每行的最后一个排列的后面不能有空格
注:全排列容易输出,重集排列不易输出,需判重。My solution:
/*2016.3.13*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,vis,h,tf;
int map[10],mark[10],path[10];
void dfs(int t)
{
int i,j;
if(t==5&&path[1]!=0)
{
if(tf)
printf(" ");
for(i=1;i<=4;i++)
printf("%d",path[i]);
//printf(" ");
vis=0;//重新回溯,查找下一个排列,需再次打开判重开关
h=1;//打开换行开关,表明当前行输出的全排列的千分位不为0,因此该行输出完后,需要输出换行
tf=1;//打开空格开关,当每一行的第一个排列输出完后,接下来的排列前都需输出空格
return ;
}
for(i=0;i<4;i++)
{
if(!mark[i])
{
if(map[i]!=path[t]||vis)
{
vis=1;//关闭判重开关
mark[i]=1;
path[t]=map[i];
dfs(t+1);
mark[i]=0;
}
}
if(t==1&&h)//每一行结果输出完后要换行,t==1表示相同千分位的排列已经输出完了,接下来要输出下一个千分位不同的排列
{ //h是表示在上一个千分位时,有结果输出,则换行。若上一组千分位为0,根据题意可知不输出,因此不需要换行
printf("\n");
h=0;//关闭换行开关,换完行后,h需重新置为0,以便为下一次的换行做准备
tf=0;//关闭空格开关,换完行后,接下来要输出新的一行排列,新的一行中的第一个排列不需要输出空格
}
}
vis=0;//当前函数执行完毕,结束调用,继续回溯,因此需要打开判重开关
}
int main()
{
int i=0,j,k;
while(scanf("%d%d%d%d",&map[0],&map[1],&map[2],&map[3])==4&&(map[0]||map[1]||map[2]||map[3]))
{
if(i!=0)//每组输出结果之间有一个空行,最后一组结尾没有
printf("\n");
i=1;
vis=0;//初始化去重开关
h=0;//初始化换行开关
tf=0;//初始化空格开关
memset(path,0x3f,sizeof(path));
memset(mark,0,sizeof(mark));
sort(map,map+4);
dfs(1);
}
return 0;
}