http://codeforces.com/contest/469/problem/D

题目大意:

给你一个长度为n数组,给你两个集合A、B,再给你两个数字a和b。A集合中的每一个数字x都也能在a集合中找到x-a的数字。同理,b集合也一样。问,这个数组能否分成这两个集合?(然后坑点就是集合里面的元素可以为空)

思路一:

首先定义type函数,-1表示不在任何集合内,0表示A集合内,1表示B集合,2表示该元素是a的一半。(之所以要表示成2的原因是因为这个数值很特殊,a-x=x,所以他可以满足A集合,但是同时也可能存在ty=-1的数值y,他的b-y=x,所以这个时候集合是可以发生改变的)

我们先暴力枚举并且二分找一下满足条件数组A里面的元素。再找一下数组B里面的元素,且在找这个数组B的时候不能修改A中集合中的元素(即ty=0)。

然后我们暴力发现还存在ty=-1的数值,那么他肯定不满足属于A集合,因此可能是属于B集合的,所以我们对该元素进行bfs一下就好了。

复杂度O(n)

  1. //看看会不会爆int!数组会不会少了一维!
  2. //取物问题一定要小心先手胜利的条件
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. #pragma comment(linker,"/STACK:102400000,102400000")
  6. #define LL long long
  7. #define ALL(a) a.begin(), a.end()
  8. #define pb push_back
  9. #define mk make_pair
  10. #define fi first
  11. #define se second
  12. #define haha printf("haha\n")
  13. const int maxn = 1e5 + ;
  14. int p[maxn], ans[maxn], ty[maxn];
  15. map<int, int> id;
  16. int a, b, n;
  17.  
  18. ///a type is 0,b is 1, 2 is suit for a
  19. void bfs(int w){
  20. queue<int> que;
  21. que.push(w);
  22. while (!que.empty()){
  23. int pos = que.front(); que.pop();
  24. int bval = b - p[pos];
  25. int mypos = lower_bound(p, p + n, bval) - p;
  26. if (p[mypos] == bval) {
  27. if (ty[mypos] != ) {
  28. int aval = a - p[mypos];
  29. int sonpos = lower_bound(p, p + n, aval) - p;
  30. if (p[sonpos] != aval) continue;
  31. if (ty[sonpos] != ){
  32. que.push(sonpos);
  33. ty[sonpos] = -;
  34. }
  35. }
  36. else continue;
  37. ty[mypos] = ty[pos] = ;
  38. }
  39. }
  40. }
  41.  
  42. bool solve(){
  43. if (p[n] >= a && p[n] >= b) return false;
  44. ///集合在a里面
  45. for (int i = ; i < n; i++){
  46. if (p[i] >= a) break;
  47. if (ty[i] == ) continue;
  48. if (p[i] * == a) {
  49. ty[i] = ; continue;
  50. }
  51. int val = a - p[i];
  52. int pos = lower_bound(p, p + n, val) - p;
  53. if (pos >= n || p[pos] != val) continue;
  54. if (ty[pos] == -){
  55. ty[pos] = , ty[i] = ;
  56. }
  57. }
  58. ///集合在b里面
  59. for (int i = ; i < n; i++){
  60. if (p[i] >= b) break;
  61. if (ty[i] == || ty[i] == ) continue;
  62. if (p[i] * == b && ty[i] == -){
  63. ty[i] = ; continue;
  64. }
  65. int val = b - p[i];
  66. int pos = lower_bound(p, p + n, val) - p;
  67. if (pos >= n || p[pos] != val || ty[pos] == ) continue;
  68. if (ty[pos] == - || ty[pos] == ){
  69. ty[pos] = , ty[i] = ;
  70. }
  71. }
  72. for (int i = ; i < n; i++)
  73. if (ty[i] == -) bfs(i);
  74. for (int i = ; i < n; i++){
  75. if (ty[i] == -) return false;
  76. if (ty[i] == ) ty[i] = ;
  77. }
  78. return true;
  79. }
  80.  
  81. int main(){
  82. int cnt = ;
  83. cin >> n >> a >> b;
  84. for (int i = ; i < n; i++){
  85. scanf("%d", p + i);
  86. id[p[i]] = cnt++;
  87. }
  88. sort(p, p + n);
  89. memset(ty, -, sizeof(ty));
  90. bool flag = solve();
  91. if (flag){
  92. puts("YES");
  93. for (int i = ; i < n; i++){
  94. int myid = id[p[i]];
  95. ans[myid] = ty[i];
  96. }
  97. for (int i = ; i < n; i++){
  98. printf("%d ", ans[i]);
  99. }
  100. cout << endl;
  101. }
  102. else puts("NO");
  103. return ;
  104. }

思路二:

当然,这题还可以用并查集来分配

假定,如果存在x,在数列中不存在a-x的数字,那么他一定属于集合B,同理,存在x,在数列中不存在b-x的数字,那么他一定属于集合A。然后我们只要利用这个条件,然后用并查集维护一下就好了。

这个的话可以看这个人的代码:链接在此

贪心+bfs 或者 并查集 Codeforces Round #268 (Div. 2) D的更多相关文章

  1. DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph

    题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...

  2. 01背包dp+并查集 Codeforces Round #383 (Div. 2)

    http://codeforces.com/contest/742/problem/D 题目大意:有n个人,每个人有重量wi和魅力值bi.然后又有m对朋友关系,朋友关系是传递的,如果a和b是朋友,b和 ...

  3. Codeforces Round #268 (Div. 2) ABCD

    CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...

  4. Codeforces Round #268 (Div. 2) (被屠记)

    c被fst了................ 然后掉到600+.... 然后...估计得绿名了.. sad A.I Wanna Be the Guy 题意:让你判断1-n个数哪个数没有出现.. sb题 ...

  5. Codeforces Round #268 (Div. 2) D. Two Sets [stl - set + 暴力]

    8161957                 2014-10-10 06:12:37     njczy2010     D - Two Sets             GNU C++     A ...

  6. Codeforces Round #268 (Div. 1) B. Two Sets 暴力

    B. Two Sets Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/468/problem/B ...

  7. Codeforces Round #268 (Div. 1) A. 24 Game 构造

    A. 24 Game Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/468/problem/A D ...

  8. Codeforces Round #268 (Div. 2)

    补题解: E:只会第四种解法:也只看懂了这一种. PS:F[X+10^18]=F[X]+1;F[X]表示X的数字之和; 假设X,F[10^18+X]+F[10^18+X-1]+......F[10^1 ...

  9. Codeforces Round #268 (Div. 1) 468D Tree(杜教题+树的重心+线段树+set)

    题目大意 给出一棵树,边上有权值,要求给出一个1到n的排列p,使得sigma d(i, pi)最大,且p的字典序尽量小. d(u, v)为树上两点u和v的距离 题解:一开始没看出来p需要每个数都不同, ...

随机推荐

  1. RF接口测试本地环境部署

    ##1 Python环境及robotframework安装 ###1.1 安装python 2.7.9(自带pip) + 下载python,双击msi文件安装 >https://www.pyth ...

  2. em,strong,b,i的区别

    文章来源: http://www.zhihu.com/question/19551271 默认样式: strong=b=粗体 em=i=斜体   HTML4.01: strong,em代表语义,从语义 ...

  3. Web程序和应用程序服务器[转]

    转自:http://hi.baidu.com/lclkathy/blog/item/dae3be36763a47370b55a970.html 一 常见的WEB服务器和应用服务器 在UNIX和LINU ...

  4. 设计模式 装饰模式(Decorator)

    设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...

  5. hdu 1022 Train Problem I(栈)

    #include<iostream> #include<vector> #include<cstring> #include<string> #incl ...

  6. Java使用千分位并保留两位小数

    double d = 123456.789; DecimalFormat df = new DecimalFormat("#,##0.00"); System.out.printl ...

  7. 如何利用 MembershipUser 更改密码

    如何利用 MembershipUser 更改密码 作者: vkvi 来源:千一网络 (原创) 时间: 2009-3-11   完美集成.增强 KindEditor HTML 编辑器 在 ASP.NET ...

  8. AIX 永久修改环境变量

    转自:http://blog.sina.com.cn/s/blog_5e3122450100stk5.html 方法一:PATH=$PATH:/usr/XX        export PATH重启一 ...

  9. redis的适应场景

    redis应用场景: 1.对数据高并发读写 2.对海量数据的高效存储和访问 3.对数据的高可扩展性和高可用性 做分布式扩展很简单,因为没有固定的表结构 redis介绍: redis是一个key-val ...

  10. 移动前端不得不了解的HTML5 head 头标签(中上篇)

    Meta 标签 meta标签是HTML中head头部的一个辅助性标签,它位于HTML文档头部的 <head> 和 <title> 标记之间,它提供用户不可见的信息.虽然这部分信 ...