【模拟题】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; }

浙公网安备 33010602011771号