标签:
题目连接:
http://www.lightoj.com/volume_showproblem.php?problem=1084
题目大意:
有n个点在一条以零为起点的坐标轴上,每个点最多可以移动k,问最终能不能把所有点都聚集在大于等于三个点的集合里面,如果能最少需要几个这样的集合?
解题思路:
刚开始看到题目感觉好简单,就开始了sort然后贪心之旅,这就是错误的开始。最后发现这样并不行,然后再Alex的提醒下想用单调队列优化,在我愚昧的理解下竟然写成了bfs,提交竟然ac了,surprise~~~
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100005; 5 const int INF = 0x3f3f3f3f; 6 int a[maxn], vis[maxn], n, k; 7 struct node 8 { 9 int x, index; 10 }; 11 12 int solve () 13 { 14 queue <node> Q; 15 node p, q; 16 17 memset (vis, 0, sizeof(vis)); 18 p.index = 0; 19 p.x = 0; 20 Q.push(p); 21 vis[0] = 1; 22 23 while (!Q.empty()) 24 { 25 p = Q.front(); 26 Q.pop(); 27 28 if (p.index >= n) 29 return p.x; 30 31 int temp = p.index; 32 while (temp<n && a[temp]-a[p.index]<=2*k) 33 temp ++; 34 35 int num = temp - p.index; 36 if (num >= 3 && !vis[temp]) 37 { 38 q.index = temp; 39 q.x = p.x + 1; 40 Q.push(q); 41 vis[temp] = 1; 42 } 43 if (num >= 4 && !vis[temp-1]) 44 { 45 q.index = temp-1; 46 q.x = p.x + 1; 47 Q.push(q); 48 vis[temp-1] = 1; 49 } 50 if (num >= 5 && !vis[temp-2]) 51 { 52 q.index = temp-2; 53 q.x = p.x + 1; 54 Q.push(q); 55 vis[temp-2] = 1; 56 } 57 } 58 return -1; 59 } 60 int main () 61 { 62 int t, l = 0; 63 scanf ("%d", &t); 64 while (t --) 65 { 66 scanf ("%d %d", &n, &k); 67 for (int i=0; i<n; i++) 68 scanf ("%d", &a[i]); 69 sort (a, a+n); 70 71 int res = solve(); 72 printf ("Case %d: %d\n", ++l, res); 73 } 74 }
暑期训练狂刷系列——Lightoj 1084 - Winter bfs
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4614724.html