链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
dd作为体操队队长,在给队员们排队形,体操队形为一个单独的纵列,体操队有n个同学,标号为1∼n,对于i(1≤i≤n)号队员,会有一个诉求(1≤a[i]≤n),表示他想排在a[i]号队员前面,当a[i]=i时,我们认为他没有位置需求,随便排哪儿都行,dd想知道有多少种队形方案,可以满足所有队员的要求。
输入描述:
读入第一行一个数字n(2≤n≤10) 第二行n个数字,表示a[i],保证1≤a[i]≤n
输出描述:
输出一行,表示方案数
示例1
输入
3 1 1 2
输出
1
解题思路:
利用全排列枚举每一种情况,看看每种情况是否符合题目所给的排队条件,如果符合则答案加一,最后输出答案就可以了
怎么判断每种情况是否符合排队条件?我设立一个vis数组,我每次从头到尾遍历所有的人,保证最先遍历的是最先出现在排队中的人,因为我的a[i]表示第i个人想排在a[i]之前,我用vis[a[i]]判断一下a[i] 出没出现过,要是没出现,那么i先出现在排队中就是可以的,否则这个排队顺序就不行,如果这个排队中每个人都符合vis[a[i]]等于0,那么这个排队顺序就是符合题目要求的答案加一
下面附上ac代码
#include <bits/stdc++.h>
using namespace std;
vector<int> ve;
int a[15];
int vis[15];
int n;
int ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ve.push_back(i);
}
do{
int flag=1;
for(auto it : ve) //从头到尾遍历,保证先遍历的最先出现
{
if(vis[a[it]]) //我要放在a[i]之前,那么判断a[i]出没出现过
{
flag=0;
break;
}
vis[it]=1; //既然a[i]没有出现过,那么我置it被访问
}
if(flag) ans++;
for(int i=1;i<=n;i++) vis[i]=0;
}while(next_permutation(ve.begin(),ve.end()));
printf("%d\n",ans);
//system("pause");
return 0;
}