【BZOJ】1665: [Usaco2006 Open]The Climbing Wall 攀岩(spfa)

Bessie参加了一个爬墙比赛,墙宽30000mm,高H(1001<=H<=30000),墙上有F(1<=F<=10000)个不同落脚点,距离至少300mm。Bessie从不超过1000mm高的任意点开始,每次移动不能超过1000mm,目标是最少攀爬次数到达至少H-1000mm的高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.lydsy.com/JudgeOnline/problem.php?id=1665

这题只要注意到“所有的落脚点至少相距300”就可以大胆的暴力了。

对于每个点,我们枚举比他的x轴小1000内和大1000内的点连边,然后直接暴力出奇迹。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=10005, M=N*50, oo=~0u>>2;
int ihead[N], cnt, n, h, vis[N], d[N], q[N], tail, front;
struct ED { int to, next; }e[M];
struct nd { int x, y, id; }a[N];
bool cmp(const nd &a, const nd &b) { return a.x<b.x; }
bool cmp2(const nd &a, const nd &b) { return a.y<b.y; }
void add(int u, int v) {
	e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v;
}
void spfa(int s) {
	for1(i, 1, n+1) d[i]=oo;
	vis[s]=1; q[tail++]=s;
	while(tail!=front) {
		int u=q[front++], v; if(front==N) front=0; vis[u]=0;
		for(int i=ihead[u]; i; i=e[i].next) if(d[v=e[i].to]>d[u]+1) {
			d[v]=d[u]+1;
			if(!vis[v]) {
				vis[v]=1;
				q[tail++]=v; if(tail==N) tail=0;
			}
		}
	}
}

inline int dis(const nd &x, const nd &y) {
	return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);
}
int main() {
	read(h); read(n);
	int S=0, T=n+1;
	for1(i, 1, n) read(a[i].x), read(a[i].y), a[i].id=i;
	sort(a+1, a+1+n, cmp2);
	for1(i, 1, n) if(a[i].y<=1000) add(S, a[i].id); else break;
	for3(i, n, 1) if(a[i].y>=h-1000) add(a[i].id, T); else break;
	sort(a+1, a+1+n, cmp);
	for1(i, 1, n) {
		int l, r;
		for(l=i-1; l>=1; --l) if(a[i].x-a[l].x>1000) break; if(l!=1) ++l;
		for(r=i+1; r<=n; ++r) if(a[r].x-a[i].x>1000) break; if(r!=n) --r;
		for1(j, l, r) if(i!=j && dis(a[i], a[j])<=1000000) {
			add(a[i].id, a[j].id);
		}
	}
	spfa(S);
	int ans=d[T];
	if(ans==oo) ans=-1;
	print(ans-1);
	return 0;
}

 

 


 

 

Description

One of the most popular attractions at the county fair is the climbing wall. Bessie wants to plan her trip up the wall in advance and needs your help. The wall is 30,000 millimeters wide and H (1001 <= H <= 30,000) millimeters high and has F (1 <= F <= 10,000) hoof-holds at unique X,Y coordinates expressed in millimeters. 0,0 is at the ground level on the left side of the wall. Hoof-holds are separated by at least 300 millimeters since no cow can maneuver them if they are spaced too close! Bessie knows there is at least one way up. Bessie, through techniques only she knows, uses successive single hoof-holds to climb the wall. She can only move from one hoof-hold to another if they are no more than one meter apart. She can, of course, move up, down, right, left or some combination of these in each move. Similarly, once she gets to a hoof-hold that is at least H-1000 millimeters above the ground, she can nimbly climb from there onto the platform atop the wall. Bessie can start at any X location that has a Y location <= 1000 millimeters. Given the height of the wall and the locations of the hoof-holds, determine the smallest number of hoof-holds Bessie should use to reach the top.

 

Bessie参加了爬墙比赛,比赛用的墙宽30000,高H(1001 <= H <= 30,000)。墙上有F(1 <= F <= 10,000)个不同的落脚点(X,Y)。 (0,0)在左下角的地面。所有的落脚点至少相距300。Bessie知道至少有一条路可以上去。 Bessie只能从一个落脚点爬到另一个距离不超过1000的落脚点,她可以向上下左右四个方向爬行。同样地,一旦她到达了一个高度 至少有H-1000的落脚点,她可以敏捷地爬到墙顶上。Bessie一开始可以在任意一个高度不超过1000的落脚点上。问Bessie至少攀爬多少次. 这里两个点的距离都是欧几里得距离

Input

* Line 1: Two space-separated integers, H and F.

* Lines 2..F+1: Each line contains two space-separated integers (respectively X and Y) that describe a hoof-hold. X is the distance from the left edge of the climbing wall; Y is the distance from the ground.

Output

* Line 1: A single integer that is the smallest number of hoof-holds Bessie must use to reach the top of the climbing wall.

Sample Input

3000 5
600 800
1600 1800
100 1300
300 2100
1600 2300

INPUT DETAILS:

The wall is three meters high with 5 hoof-holds.

Sample Output

3

HINT

 分别经过(600,800), (100,1300), (300,2100)

Source

转载于:https://www.cnblogs.com/iwtwiioi/p/3970894.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值