题目描述:
链接:https://www.nowcoder.com/questionTerminal/52f25c8a8d414f8f8fe46d4e62ef732c
来源:牛客网
小多想在美化一下自己的庄园。他的庄园毗邻一条小河,他希望在河边种一排树,共 M 棵。小多采购了 N 个品种的树,每个品种的数量是 Ai (树的总数量恰好为 M)。但是他希望任意两棵相邻的树不是同一品种的。小多请你帮忙设计一种满足要求的种树方案。
链接:https://www.nowcoder.com/questionTerminal/52f25c8a8d414f8f8fe46d4e62ef732c
来源:牛客网
输入描述:
第一行包含一个正整数 N,表示树的品种数量。
第二行包含 N 个正整数,第 i (1 <= i <= N) 个数表示第 i 个品种的树的数量。
数据范围:
1 <= N <= 1000
1 <= M <= 2000
输出描述:
输出一行,包含 M 个正整数,分别表示第 i 棵树的品种编号 (品种编号从1到 N)。若存在多种可行方案,则输出字典序最小的方案。若不存在满足条件的方案,则输出"-"。
示例1
输入:
3 4 2 1
输出
1 2 1 2 1 3 1
思路分析:
这题需要用dfs和回溯来求解。同时需要剪枝来防止超时。
代码:
1 #include<stdio.h> 2 #include<iostream> 3 #include<stdlib.h> 4 #include<vector> 5 #include<algorithm> 6 #include<limits.h> 7 using namespace std; 8 9 int find_max(int tree[], int n) 10 { 11 int max_val = 0; 12 int max_idx = -1; 13 for(int i=0; i<n; i++) 14 { 15 if(tree[i] > max_val) 16 { 17 max_val = tree[i]; 18 max_idx = i; 19 } 20 } 21 return max_idx; 22 } 23 24 bool dfs(int tree[], int res[], int n, int& m, int step) 25 { 26 int idx = find_max(tree, n); 27 if(idx == -1) 28 return true; 29 if(tree[idx]*2> m+1) // 剪枝 30 return false; 31 if(tree[idx]*2 == m+1) 32 { 33 tree[idx]--; 34 m--; 35 res[step] = idx+1; 36 if(dfs(tree, res, n, m, step+1)) 37 return true; 38 tree[idx]++; 39 m++; 40 } 41 else 42 { 43 for(int i=0; i<n; i++) 44 { 45 if(tree[i]>0 && (step==0 || res[step-1]!=i+1)) 46 { 47 tree[i]--; 48 m--; 49 res[step] = i+1; 50 if(dfs(tree, res, n, m, step+1)) 51 return true; 52 tree[i]++; 53 m++; 54 } 55 } 56 } 57 return false; 58 } 59 60 int main() 61 { 62 int n; 63 scanf("%d",&n); 64 int tree[n]; 65 int num_tree = 0; 66 for(int i=0; i<n; i++) 67 { 68 scanf("%d", &tree[i]); 69 num_tree += tree[i]; 70 } 71 int res[num_tree]; 72 int total = num_tree; 73 if(dfs(tree, res, n, num_tree, 0)) 74 { 75 for(int i=0; i<total; i++) 76 { 77 if(i < total-1) 78 printf("%d ", res[i]); 79 else 80 printf("%d ", res[i]); 81 } 82 } 83 else 84 { 85 printf("- "); 86 } 87 return 0; 88 }