描述 Description
Matrix67发现身高接近的人似乎更合得来。Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排在圆桌上。Matrix67的安排原则是,圆桌上任意两个相邻人的身高之差不能超过K。请告诉Matrix67他共有多少种安排方法。输入格式 InputFormat
第一行输入两个用空格隔开的数N和K,其中1<=N<=10,1<=K<=1 000 000。第二行到第N+1行每行输入一个人的身高值。所有人的身高都是不超过1 000 000的正整数
输出格式 OutputFormat
输出符合要求的安排总数样例输入 SampleInput
4 10 2 16 6 10
样例输出 SampleOutput
2
搜索题,因为是围成一个圈,所以最后一个人和第一个人也要比较。
如果只是单纯的深搜,因为是圆桌所以会出现重复的情况,例如1 2 3 4 和2 3 4 1 和 3 4 1 2 和 4 1 2 3 都属于同一个。
避免重复的一种方法是先深搜求的安排总数,包括重复的,最后再将总数除以n。
还有一种方法是 固定第一个人一定在第一个位置,从第二个位置开始深搜。
一:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int n, k, count;
int a[15], b[15];
bool vis[15];
void dfs(int x)
{
if(x == n)
{
if(abs(b[n - 1] - b[0]) <= k)
{
count ++;
/*
for(int j = 0; j < n; j++)
printf("%d ", b[j]);
printf("\n");
*/
}
return ;
}
int i;
for(i = 0; i < n; i++)
{
if(vis[i] == 0)
{
if(x == 0 || abs(a[i] - b[x - 1]) <= k)
{
vis[i] = 1;
b[x] = a[i];
dfs(x + 1);
vis[i] = 0;
}
}
}
}
int main (void)
{
while(scanf("%d %d", &n, &k) != EOF)
{
int i;
for(i =0; i < n; i++)
{
scanf("%d", &a[i]);
}
//b[0] = a[0];
dfs(0);
printf("%d\n", count / n);
memset(vis, 0, sizeof(vis));
count = 0;
}
return 0;
}
二:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int n, k, count;
int a[15], b[15];
bool vis[15];
void dfs(int x)
{
if(x == n)
{
if(abs(b[n - 1] - b[0]) <= k)
{
count ++;
/*
for(int j = 0; j < n; j++)
printf("%d ", b[j]);
printf("\n");
*/
}
return ;
}
int i;
for(i = 1; i < n; i++)
{
if(vis[i] == 0)
{
if(abs(a[i] - b[x - 1]) <= k)
{
vis[i] = 1;
b[x] = a[i];
dfs(x + 1);
vis[i] = 0;
}
}
}
}
int main (void)
{
while(scanf("%d %d", &n, &k) != EOF)
{
int i;
for(i =0; i < n; i++)
{
scanf("%d", &a[i]);
}
b[0] = a[0];
dfs(1);
printf("%d\n", count);
memset(vis, 0, sizeof(vis));
count = 0;
}
return 0;
}