Clique Problem
巧妙的贪心。最近发现自己很多板块都能力不足,比如思维和贪心等知识点,这都是以前周老师不是很重视的地方(还有就是最近很容易怀旧,刚毕业的人都这样)。
想到先去绝对值。由于联通是双向的过程,所以统计一次即可,想到按x升序排序,这样点i和j(i在j后面)有连边就需要满足 \(x_i-x_j\ge w_i+w_j\) ,移项得到 \(w_i-w_i\ge w_j+x_j\) 。而很明显前者和后者都是只和i或者j有关的量,所以可以看成是轴上的许多点;而题目保证了w的非负,所以每一个点的x-w和x+w可以看成是一条线段,两个点有连边当且仅当线段右端点不大于另一条线段的左端点,即两条线段无重合部分时,问题变成了经典的贪心问题。
然后尴尬的发现写挂了,交了七八次。原因是写法有大锅,假如指针越出当前范围时是不能被统计入答案的。
code:
#include<bits/stdc++.h>
//#define zczc
#define int long long
const int N=200010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
struct node{
int a,b;
}a[N];
int m;
inline bool cmp(node s1,node s2){
if(s1.b==s2.b)return s1.a<s2.a;
else return s1.b<s2.b;
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);int s1,s2,ans=0,last=-1e12;
for(int i=1;i<=m;i++){
read(s1);read(s2);
a[i].a=s1-s2,a[i].b=s1+s2;
}
sort(a+1,a+m+1,cmp);
for(int now=1;now<=m;now++){
while(now<=m&&a[now].a<last)now++;
if(now<=m)ans++;last=a[now].b;
}
printf("%lld",ans);
return 0;
}
一如既往,万事胜意