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;
}