社区讨论

6pts球调,悬4关

P6007[USACO20JAN] Springboards G参与者 2已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
10 条
当前快照
1 份
快照标识符
@mm0d0hbi
此快照首次捕获于
2026/02/24 16:44
2 周前
此快照最后确认于
2026/02/26 09:30
2 周前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=0x7fffffff;
const int N=2e5;
int n,p;
struct node
{
	int x,y;
	int pos;
	int id;
	int step;
}num[N+5];
bool cmp1(node xx,node yy)
{
	if(xx.x==yy.x)
		return xx.y<yy.y;
	return xx.y<yy.x;
}
bool cmp2(node xx,node yy)
{
	return xx.y<yy.y;
}
int jl(int xx1,int yy1,int xx2,int yy2)
{
	return abs(xx1-xx2)+abs(yy1-yy2);
}
void cdq(int l,int r)
{
	if(l==r) return ;
	int mid=(l+r)>>1;
	cdq(l,mid);
	sort(num+l,num+mid+1,cmp2);
	sort(num+mid+1,num+r+1,cmp2);
	int i=l,j=mid+1;
	int minn=inf;
	while(j<=r)
	{
		bool flag=(num[j].x==3 && num[j].y==3);
		while(i<=mid && num[i].y<=num[j].y)
		{
			if(num[j].pos==1 && num[i].pos==2)
				minn=min(minn,num[i].step+jl(num[i].x,num[i].y,num[j].x,num[j].y));
			if(num[j].pos==2 && num[i].pos==1)
				if(num[j].id==num[i].id)
					minn=min(minn,num[i].step);
			i++;
		}
		num[j].step=minn;
		if(minn==inf) num[j].step=num[j].x+num[j].y;
		j++;
	}
	cdq(mid+1,r);
	return ;
}
signed main()
{
	cin>>n>>p;
	for(int i=1;i<=p;i++)
	{
		int xx1,yy1,xx2,yy2;
		cin>>xx1>>yy1>>xx2>>yy2;
		num[i*2-1]={xx1,yy1,1,i,inf};
		num[i*2]={xx2,yy2,2,i,inf};
	}
	num[2*p+1]={0,0,2,-1,0};
	num[2*p+2]={n,n,1,-2,0};
	sort(num+1,num+2*p+3,cmp1);
	cdq(1,2*p+2);
	cout<<num[2*p+2].step<<"\n";
	return 0;
}
可以证明有满足偏序关系的跳跃(向上、向右)一定不劣于走路,所以直接对几个跳跃路线做连接(同一路线起点连终点,不同路线终点连起点),将起点看成一个终点,终点看成一个起点。
似乎这个思路会遗漏,求问题。

回复

11 条回复,欢迎继续交流。

正在加载回复...