贪心+bfs 或者 并查集 Codeforces Round #268 (Div. 2) D
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)
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + ;
int p[maxn], ans[maxn], ty[maxn];
map<int, int> id;
int a, b, n; ///a type is 0,b is 1, 2 is suit for a
void bfs(int w){
queue<int> que;
que.push(w);
while (!que.empty()){
int pos = que.front(); que.pop();
int bval = b - p[pos];
int mypos = lower_bound(p, p + n, bval) - p;
if (p[mypos] == bval) {
if (ty[mypos] != ) {
int aval = a - p[mypos];
int sonpos = lower_bound(p, p + n, aval) - p;
if (p[sonpos] != aval) continue;
if (ty[sonpos] != ){
que.push(sonpos);
ty[sonpos] = -;
}
}
else continue;
ty[mypos] = ty[pos] = ;
}
}
} bool solve(){
if (p[n] >= a && p[n] >= b) return false;
///集合在a里面
for (int i = ; i < n; i++){
if (p[i] >= a) break;
if (ty[i] == ) continue;
if (p[i] * == a) {
ty[i] = ; continue;
}
int val = a - p[i];
int pos = lower_bound(p, p + n, val) - p;
if (pos >= n || p[pos] != val) continue;
if (ty[pos] == -){
ty[pos] = , ty[i] = ;
}
}
///集合在b里面
for (int i = ; i < n; i++){
if (p[i] >= b) break;
if (ty[i] == || ty[i] == ) continue;
if (p[i] * == b && ty[i] == -){
ty[i] = ; continue;
}
int val = b - p[i];
int pos = lower_bound(p, p + n, val) - p;
if (pos >= n || p[pos] != val || ty[pos] == ) continue;
if (ty[pos] == - || ty[pos] == ){
ty[pos] = , ty[i] = ;
}
}
for (int i = ; i < n; i++)
if (ty[i] == -) bfs(i);
for (int i = ; i < n; i++){
if (ty[i] == -) return false;
if (ty[i] == ) ty[i] = ;
}
return true;
} int main(){
int cnt = ;
cin >> n >> a >> b;
for (int i = ; i < n; i++){
scanf("%d", p + i);
id[p[i]] = cnt++;
}
sort(p, p + n);
memset(ty, -, sizeof(ty));
bool flag = solve();
if (flag){
puts("YES");
for (int i = ; i < n; i++){
int myid = id[p[i]];
ans[myid] = ty[i];
}
for (int i = ; i < n; i++){
printf("%d ", ans[i]);
}
cout << endl;
}
else puts("NO");
return ;
}
思路二:
当然,这题还可以用并查集来分配
假定,如果存在x,在数列中不存在a-x的数字,那么他一定属于集合B,同理,存在x,在数列中不存在b-x的数字,那么他一定属于集合A。然后我们只要利用这个条件,然后用并查集维护一下就好了。
这个的话可以看这个人的代码:链接在此
贪心+bfs 或者 并查集 Codeforces Round #268 (Div. 2) D的更多相关文章
- DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph
题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...
- 01背包dp+并查集 Codeforces Round #383 (Div. 2)
http://codeforces.com/contest/742/problem/D 题目大意:有n个人,每个人有重量wi和魅力值bi.然后又有m对朋友关系,朋友关系是传递的,如果a和b是朋友,b和 ...
- Codeforces Round #268 (Div. 2) ABCD
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
- Codeforces Round #268 (Div. 2) (被屠记)
c被fst了................ 然后掉到600+.... 然后...估计得绿名了.. sad A.I Wanna Be the Guy 题意:让你判断1-n个数哪个数没有出现.. sb题 ...
- Codeforces Round #268 (Div. 2) D. Two Sets [stl - set + 暴力]
8161957 2014-10-10 06:12:37 njczy2010 D - Two Sets GNU C++ A ...
- 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 ...
- 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 ...
- 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 ...
- Codeforces Round #268 (Div. 1) 468D Tree(杜教题+树的重心+线段树+set)
题目大意 给出一棵树,边上有权值,要求给出一个1到n的排列p,使得sigma d(i, pi)最大,且p的字典序尽量小. d(u, v)为树上两点u和v的距离 题解:一开始没看出来p需要每个数都不同, ...
随机推荐
- javaWEB总结(9):自定义HttpServlet
前言:我们知道 MyHttpServlet是MyGenericServlet的子类,MyHttpServlet会继承父类的方法,可是却很少去追问MyHttpServlet中的doGet方法和doPos ...
- Spring 后置处理器 PropertyPlaceholderConfigurer 类(引用外部文件)
一.PropertyPlaceholderConfigurer类的作用 PropertyPlaceholderConfigurer 是 BeanFactory 后置处理器的实现,也是 BeanFact ...
- iOS开发下架在AppStore中销售的app
1.登陆开发者账号 2.选择itunes connect 选择我的app 3.选择要下架的app 4.价格与销售范围 5.销售范围 6.点击存储 //如果想要重新在AppStore中进行销售只需要选择 ...
- spring的@Transactional注解详细用法
概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性.Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型, ...
- Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 [ 转载 ]
Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 @author Trinea 原文链接:http://www.trinea.cn/android/arrayl ...
- 6、plsql编程
一.PLSQL编程思维导图 二.PLSQL编程思维导图对应笔记 PL/SQL编程 @Holly老师 5.1 为什么学习PL/SQL编程? 当我们要批量插入100万数据,怎么办? .难道要写一百条ins ...
- Linux 抓包命令
可使用如下命令,在Linux系统上进行抓包命令 tcpdump -n -i eth0 tcp port and host 192.168.9.45 -w ./filename.cap 说明: eth0 ...
- PHP ajax 限制 API 来源限制
if(isset($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower($_SERVER["HTTP_X_RE ...
- MAC img 安装 mysql 修改密码
参考 : http://tieba.baidu.com/p/3042628829 step1: 苹果->系统偏好设置->最下边点mysql 在弹出页面中 关闭mysql服务(点击stop ...
- redis数据类型:Strings
String是最简单的数据类型,一个key对应一个value,string类型是二进制安全的,redis的String可以包含任何数据, 比如jpg图片或者系列化的对象. Set方法: 设置key对应 ...