洛谷 P12148 题解

【MX-X11-T2】所以我放弃了音乐

我们可以顺理成章地把答案转化为作为起点的点的数量。

然后我们想一个贪心策略:对于每一列的点,它一定尽可能的从上一列靠下面的点移动过来。

感性理解就是如果你下面的点不移动到这个点,那上面的点就更没有机会了;下面的点移动到这个点,不仅增加这个点的机会,还能增加这个点同列的点的机会。

所以我们对于每一列以 \(y\) 为关键字从大到小排序。

然后按照贪心策略标记不做起点的点。

最后统计做起点的点的数量。

AC code:

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int> PII;
bool cmp(PII x,PII y){
	if(x.first==y.first) return x.second>y.second;
	return x.first<y.first;
}
const int N=1e6+5;
PII p[N];
map<PII,int> mp;
int n,ans;
int read(){
	int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
		x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
signed main(){
	n=read();
	for(int i=1;i<=n;i++){
		int x,y;
		x=read(),y=read();
		p[i]=make_pair(x,y);
		mp[p[i]]=1;
	}
	sort(p+1,p+n+1,cmp);
	PII nxt;
	for(int i=1;i<=n;){
		int x=p[i].first;
		for(;p[i].first==x;i++){
			if(mp[p[i]]) ans++;
			int y=p[i].second;
			for(int j=1;j>=-1;j--){
				nxt=make_pair(x+1,y+j);
				if(mp.count(nxt)&&mp[nxt]){
					mp[nxt]=0;
					break;
				}
			}
		}
	}
	printf("%d",ans);
	return 0;
}
posted @ 2025-11-22 11:50  NiYqaq  阅读(19)  评论(0)    收藏  举报