题意:
给n个不同的整数(3<=n<=9),问你能绘制出多少种解锁的方案。
输出方案数,以及按字典序输出每种方案。
思路:
一个很水的dfs全排列,加上特判就好了。
特判就是1->9的话就必定经过5等。
这里要注意的是。
中间所经过的数字是必须存在的。
比如要想1->9就必须有5.
5要么被用过,要么就经过5
例子就是 1 3 5 9这四个数。
实际的方案是只有2种
3 5 1 9 和 3 5 9 1
然后就是输入完排下序,保证字典序。
最后就是弱太弱了,写了2个dfs一个算个数,一个输出。
代码:
#include"stdio.h"
#include"algorithm"
#include"string.h"
#include"iostream"
#include"queue"
#include"map"
#include"string"
#define mod 1000000007
using namespace std;
int mp[12][12];
int n,ans,used[123],a[123],b[123];
void f()
{
mp[1][3]=2;mp[3][1]=2;
mp[1][7]=4;mp[7][1]=4;
mp[1][9]=5;mp[9][1]=5;
mp[2][8]=5;mp[8][2]=5;
mp[3][7]=5;mp[7][3]=5;
mp[3][9]=6;mp[9][3]=6;
mp[4][6]=5;mp[6][4]=5;
mp[7][9]=8;mp[9][7]=8;
}
void dfs(int cur,int x)
{
if(x==n)
{
ans++;
return ;
}
for(int i=0;i<n;i++)
{
if(used[a[i]]==0 && (mp[cur][a[i]]==0 || used[mp[cur][a[i]]]==1))
{
used[a[i]]=1;
dfs(a[i],x+1);
used[a[i]]=0;
}
}
}
void dfs1(int cur,int x)
{
if(x==n)
{
for(int i=0;i<n;i++) printf(i==n-1?"%d\n":"%d ",b[i]);
return ;
}
for(int i=0;i<n;i++)
{
if(used[a[i]]==0 && (mp[cur][a[i]]==0 || used[mp[cur][a[i]]]==1))
{
used[a[i]]=1;
b[x]=a[i];
dfs1(a[i],x+1);
used[a[i]]=0;
}
}
}
int main()
{
int t;
cin>>t;
memset(mp,0,sizeof(mp));
f();
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n);
memset(used,0,sizeof(used));
ans=0;
dfs(0,0);
printf("%d\n",ans);
memset(used,0,sizeof(used));
dfs1(0,0);
}
return 0;
}