【模拟题】Matrix67的派对

Matrix67的派对

题目描述

    Matrix67发现身高接近的人似乎更合得来。Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排在圆桌上。Matrix67的安排原则是,圆桌上任意两个相邻人的身高之差不能超过K。请告诉Matrix67他共有多少种安排方法。

输入

    第一行输入两个用空格隔开的数N和K,其中1<=N<=10,1<=K<=1 000 000。

    第二行到第N+1行每行输入一个人的身高值。所有人的身高都是不超过1 000 000的正整数

输出

    输出符合要求的安排总数

样例输入

4 10
2
16
6
10

样例输出

2

思路:深搜,因为是圆桌,所以和顺序无关(即例如样例中身高为2的人,可以在圆桌的任何一个位置都算一种方案),和左右邻居是什么人有关,所以可以先固定一个座位上的来(例如,第一个人),其他位置开始搜索查找,填入合适的人选
有三个陷阱:①当n==1时,一个人的时候算一种方案,如果没有特判会是0种方案,解决方法是加特判
②出现身高相同的人
一开始的想法是标记身高flag[high[i]]=1,后来发现身高可能出现重复,就会出现标记过的人,下次再也没有机会填入座位,方案数为0,后来修改为再读入的时候做flag[high[i]]++,处理,一旦有数据填入,就做flag[high[i]]-- 处理,满足填入的条件改为:abs(high[i] - a[step -1]) <= k && flag[i],通过了,直到遇到陷进③

③出现多个身高相同的人
怎么去标记一个人使得他具有唯一性,身高有可能重复,因为标记身高不行,但是读入数据时顺序可以作为一个人的标识,后来改为标记读入数据的数组下标flag[i]

实现代码:
#include<bits/stdc++.h>
using namespace std;
int n,ans,k,high[12],flag[12],a[12];
void dfs(int step)
{
    int i;
        for( i = 2 ; i <= n ; i++)
        {
            if(abs(high[i] - a[step -1]) <= k && !flag[i])
            {
                flag[i] ++;
                a[step] = high[i];
                if(step == n && abs(a[step] - a[1]) <= k)
                {
                    ans++;
                }
                else
                dfs(step+1);
                flag[i] --;
            }
        }
}
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    cin >> n >> k;
    int i;
    for( i = 1 ; i <= n ; i++ )
    {
        cin >> high[i];
    }
    if(n == 1)
    ans = 1;
    else
    {
        flag [1]++;
        a[1] = high[1];
        dfs(2);
    }
    cout << ans;
    return 0;
}

 




posted @ 2018-10-26 16:01  LizLiz  阅读(913)  评论(0)    收藏  举报