51nod 1557 两个集合 (严谨的逻辑题)
题目:
小X有n个互不相同的整数: p1,p2,...,pn 。他想把这些整数分到两个集合A和B里边。但是要符合下面两个条件。
· 如果x属于A,那么a-x也肯定属于A。
· 如果x属于B,那么b-x也肯定属于B。
判断一下是否存在一种方案来分配这些数字到集合A,B中。
注意:如果一个集合为空也是可以的。
单组测试数据。
第一行有三个整数n,a,b (1≤n≤10^5; 1≤a,b≤10^9)。
第二行有n个不一样的整数 p1,p2,...,pn (1≤pi≤10^9).
如果可行,那么输出YES,否则输出NO。
样例输入1
4 5 9
2 3 4 5
样例输出1
YES 题意很清楚就是把所有的数字按要求分在A,B集合中,看是否能全部分完。 看似很简单,但是有很多坑点,需要把所有的逻辑都想清楚再下笔。 解法:
首先我们看到这道题肯定会想到二分图的解法。
二分图是相邻的点要染成不同色,看是否能把整个图只用两种颜色染色。
这道题是相邻的点(a[i]+a[j]==A || a[i]+a[j]==B)要染成同色,看是否能用两种颜色表示。(注意的是两种颜色可能相同(A == B))
但是和二分图很不同的是,当一个点可以在A中而且可以在B中时,用二分图的逻辑有点行不通了。 所以我们换个思路:
当某个点只能存在A中/只能存在于B中时,我们就把这个点和与之匹配的点(A-a[i]/B-a[i])放在A/B中。
一趟一趟的扫所有的点,如果某一次没有能放在A/B中的点了,
1.n个点中还有点没有被放在A/B中,那就不能分完,输出NO。
2.n个点全部放在A/B中了,那就能分完,输出YES。 注意的就是如果A == B,可能会陷入死循环,需要特殊处理A == B,直接看是否能将全部点放在A/B中就可以。 代码:
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <math.h>
#include <queue>
using namespace std;
typedef long long ll;
#define INF 2147483647 int s[]; map<int, bool> in; // 表示数字没有被使用过,所有的数字都在大集合里 int main(){
int n,a,b;
cin >> n >> a >> b;
for(int i = ;i < n; i++){
cin >> s[i];
in[s[i]] = true;
} int count = ; //记录多少个数字被使用过 while(true){
//标记当前循环是否有数字匹配
bool update = false; for(int i = ;i < n; i++){
if(!in[s[i]]) continue; //这个数字被使用过了,不再计算
if(in[a-s[i]] && !in[b-s[i]]){
//在A集合中能找到匹配对象,B集合中找不到,一定要放在A集合中
in[a-s[i]] = false;
in[s[i]] = false;
count += ;
update = true;
}else if(!in[a-s[i]] && in[b-s[i]]){
//在B集合中能找到匹配对象,A集合中找不到,一定要放在B集合中
in[b-s[i]] = false;
in[s[i]] = false;
count += ;
update = true;
}else if(in[a-s[i]] && in[b-s[i]] && a == b){
//如果a == b,全部放在一个集合中就可以了
in[a-s[i]] = false;
in[s[i]] = false;
count += ;
update = true;
}
}
//如果放了n个数字了,说明可以分配
if(count >= n) break;
//如果放不够n个数字,而且再也找不到匹配了,说明无法分配
if(!update){
cout << "NO" << endl;
return ;
}
}
cout << "YES" << endl;
return ;
}
51nod 1557 两个集合 (严谨的逻辑题)的更多相关文章
- 51Nod 1557 两个集合(二分)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1557 题意: 小X有n个互不相同的整数: p1,p2,...,pn .他 ...
- java求两个集合的交集和并集,比较器
求连个集合的交集: import java.util.ArrayList; import java.util.List; public class TestCollection { public st ...
- 求两个集合的交集和并集C#
我是用hashset<T>来实现的 具体如代码所示 using System; using System.Collections.Generic; using System.Linq; u ...
- 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象
本文需要对C#里的LINQ.Lambda 表达式 .委托有一定了解. 在工作中,经常遇到需要对比两个集合的场景,如: 页面集合数据修改,需要保存到数据库 全量同步上游数据到本系统数据库 在这些场景中, ...
- 计算两个集合的差集——第六期 Power8 算法挑战赛
第六期Power8大赛 1.1 比赛题目 题目: 计算两个集合的差集: 详细说明: 分别有集合A和B两个大数集合,求解集合A与B的差集(A中有,但B中无的元素),并将结果保存在集合C中,要求集合C中的 ...
- c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)
c#封装DBHelper类 public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...
- C# 判断两个集合(List)是否相等
1.两个list如果有重复元素(如List1: a,b,a List2: b,b,a) 是无法通过包含关系来判断是否相等的. 有两个办法,其一是两个List排序后再按顺序比较.另一个办法就是计算各元 ...
- 关于Linq对DataTable和List各自的两个集合筛选的相关操作技巧
项目中用到了对两个集合的帅选等操作,简单总结下 1.Linq操作多个Datable 可以通过AsEnumerable()方法对DataTable进行Linq操作 //获取数据表所有数据 DataTab ...
- Java 单个集合去重与两个集合去重
一.单个集合去重 描述: 去掉一个集合里重复的元素:将list集合转成hashSet集合,hashSet有自动去重的功能,再利用去重后的hashSet集合初始化一个新的list集合,此时这个list就 ...
随机推荐
- 枚举所有排列-STL中的next_permutation
枚举排列的常见方法有两种 一种是递归枚举 另一种是STL中的next_permutation //枚举所有排列的另一种方法就是从字典序最小排列开始,不停的调用"求下一个排列"的过程 ...
- 探讨:crond 引发大量sendmail进程的解决办法
某服务器账号comm无法登录,说是资源消耗完毕.于是用另一个账号登陆到服务器,检查common账号到底启动了哪些dd引起资源耗尽:ps -u common发现有个 sendmail的启动特别多例如:c ...
- Apache负载均衡配置
使用mod_proxy 配置Apache负载均衡 1.安装apache ./configure --prefix=/usr/local/apache2 –enable-so make &&am ...
- Android琐碎知识点集合
1.最近发现android studio更新之后用的v7包,每次创建Activity的时候自动继承的是AppCompatActivity,很不舒服,还是习惯Activity.没什么大的毛病,毕竟goo ...
- svn: E155017: Checksum mismatch while updating 校验错误的解决方法
[10.3.53.53:/EMRCV5]# svn up svn: E155004: Working copy '/EMRCV5' locked. svn: E155004: '/EMRCV5' is ...
- Eclipse中使用GIT更新项目
GIT更新项目: 右击项目——Team——Pull:
- APICloud资料
//语音读text里面的文字 var text=document.getElementById('ready').value; alert(text); var obj = api.require(' ...
- PHP SOAP 使用示例
soap_client.php <?php try { $client = new SoapClient( null, array('location' =>"http://lo ...
- 如何在React-Native上使用Typescript
首先安装脚手架: $ yarn global add create-react-native-app 创建项目: create-react-native-app xxx 进入项目并启动: cd xxx ...
- BZOJ 1016 最小生成树计数(矩阵树定理)
我们把边从小到大排序,然后依次插入一种权值的边,然后把每一个联通块合并. 然后当一次插入的边不止一条时做矩阵树定理就行了.算出有多少种生成树就行了. 剩下的交给乘法原理. 实现一不小心就会让程序变得很 ...