codeforces 527D:脑洞题

表示这类题目完全不会

把表达式转化后:

xi+wi<=xj-wj (xi<=xj)

xj+wj<=xi-wi (xi>=xj)

好像还是看不出什么- -||  

满足上式的i j两点就能抱团,那我们要找尽量多的点满足上述关系

其实上述两个式子是等价的(想一想)

所以只需要满足xi+wi<=xj-wj的两个点就能抱团

那我们的策略是贪心,要尽量多的点满足这个式子的话,自然xi+wi越小越好,所以我们按xi+wi排序

这样得到的序列,每一个元素只需要和前一个元素判断一下就好,因为如何i和i-1符合这个式子的话,和之前的点是必然符合的(因为我们是按照xi+wi排序的,之前的点xi+wi肯定小于等于当前点)

#include"cstdio"
#include"queue"
#include"cmath"
#include"stack"
#include"iostream"
#include"algorithm"
#include"cstring"
#include"queue"
#include"map"
#include"vector"
#define ll long long
#define mems(a,b) memset(a,b,sizeof(a))
#define ls pos<<1
#define rs pos<<1|1

using namespace std;
const int MAXN = 200500;
const int MAXE = 200500;
const int INF = 0x3f3f3f3f;

struct nn{
    int w,x;
}node[MAXN];

bool cmp(nn a,nn b){
    return a.x+a.w<b.w+b.x;
}

int main(){
    int n;scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",&node[i].x,&node[i].w);
    sort(node,node+n,cmp);
    int ans=1;
    int t=node[0].x+node[0].w;
    for(int i=1;i<n;i++){
        if(node[i].x-node[i].w>=t){
            ans++;
            t=node[i].x+node[i].w;
        }
    }
    cout<<ans<<endl;
    return 0;
}
时间: 2025-01-01 21:01:10

codeforces 527D:脑洞题的相关文章

51nod 1380 夹克老爷的逢三抽一 堆 脑洞题

51nod 1380 夹克老爷的逢三抽一堆 脑洞题 题意 n个人围成一圈 然后每次可以选一个人,得到他的分数,然后他与他相邻的两个人出圈 总共选 n/3次, 保证n是3的倍数 题解 这道怎么说呢,应该比较巧妙吧,你开一个优先队列,大根堆,每次选择优先队列中最大的数,然后把他左右两个数删掉,比如 A B C 删掉 B ,那么就把 A+C-B 加入优先队列中,这其实就是相当于提供了一个后悔的机会,就像网络流中的反向边,如果在选中这个点的话,就相当于 B+(A+C-B) 然后就相当于 B 这个点 不选

图论(KM算法,脑洞题):HNOI 2014 画框(frame)

值得一写的脑洞题! 最开始没有任何思路,看了题解后才会做. 考虑将a的和与b的和表示为坐标,那么可能为答案的点一定是下凸包中的点,这样优化枚举就保证了效率. 然而并不知道到底哪些点是凸包中的点,但我们知道边界的两点(a最小于b最小)一定在凸包上,如果已知两个凸包上的点,我们将它们连线,那么属于原图中的点若距离此直线最远,则一定是凸包上的点,于是可以二分,用向量的叉积求出那个点. 1 #include <iostream> 2 #include <cstring> 3 #includ

Codeforces VP/补题小记 (持续填坑)

Codeforces VP/补题小记 1149 C. Tree Generator 给你一棵树的括号序列,每次交换两个括号,维护每次交换之后的直径. ? 考虑括号序列维护树的路径信息和,是将左括号看做 \(-1\) ,右括号看做 \(1\) ,那么一段竖直向上的路径可以表示为括号序列的一个区间和,一段竖直向下的路径可以看做括号序列的一个区间和的相反数.我们要维护的是树的直径,也就是一段连续的和减去紧随其后的一段连续的差.具体来说就是 \[ \max_{\forall [l,r]}\{\sum_{

CodeForces - 427B (模拟题)

Prison Transfer Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description The prison of your city has n prisoners. As the prison can't accommodate all of them, the city mayor has decided to transfer c of t

codeforces 984补题

codeforces 984a 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 int num[1010]; 5 int main(){ 6 scanf("%d",&n); 7 for(int i=1;i<=n;i++) scanf("%d",&num[i]); 8 sort(num+1,num+n+1); 9 if(n%2==1) printf("%

codeforces 乱做题记录

Codeforces 590 E https://codeforces.com/problemset/problem/590/E 给 $ n $ 个只包含字符 $ a $ 和 $ b $ 的字符串,总长度不超过 $ 10^7 $,选出最多的字符串,使得其中不存在字符串 $ a $ 和 $ b $ 满足 $ a $ 是 $ b $ 的子串,输出方案,如果有多种方案,输出任意一种 $ n \le 750 $ 我们需要对每个串求出所有的比它短的是它的子串的字符串,并向其连边,可以发现这 $ n $ 个

B - Save the problem! CodeForces - 867B 构造题

B - Save the problem! CodeForces - 867B 这个题目还是很简单的,很明显是一个构造题,但是早训的时候脑子有点糊涂,想到了用1 2 来构造, 但是去算这个数的时候算错了... 用1 2 来构造 可以先枚举一些数来找找规律. 1 1 2 2 3 1 1 1    2 1 1 4 .... 可以发现每一个数都是 n/2+1 的可能, 所以反过来推过去就是 (s-1)*2  或者(s-1)*2+1 这个(s-1)*2+1的答案才是正确答案 因为 这个s可以==1 #i

codeforces打完补题

https://codeforces.com/contest/1234/problem/D 写了个巨蠢的线段树(不愧是垃圾),有必要提醒下自己这种题怎么做 #include<iostream> #include<cstdio> #include<string> #include<set> #include<algorithm> using namespace std; const int maxn = 32; set<int> st[

Codeforces Hello2015第一题Cursed Query

英文题面: De Prezer loves movies and series. He has watched the Troy for like 100 times and also he is a big fan of Supernatural series.So, he did some researches and found a cursed object which had n lights on it and initially all of them were turned of