贪心BFS

题目 Tractor.
代码很好写,就是在经典bfs基础上加一个贪心的思想
从起点开始,往四个方向走,碰到有草的且没有走过的就放在最前面优先搜索(可以用双端队列或者优先队列实现);
到原点就输出草的数量;
优先队列代码

#include<bits/stdc++.h>
#define ll long long
#define T int t;scanf("%d", &t);while(t--)
using namespace std;
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
const ll mod = 1e9+7;
const int maxn = 2e5+5;
int vis[1005][1005]={0};	//标记草
int book[1005][1005]={0};	//标记是否走过
int n;
int s, t;
int main(){
	scanf("%d %d %d", &n, &s, &t);
	for(int i = 0; i < n; i++){
		int x,y;
		scanf("%d %d", &x, &y);
		vis[x][y] = 1;			//有草标记1
	}
	//优先队列 要删去草的数量少的前面先搜,小顶堆
	priority_queue<pair<int,pair<int,int> >, vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int> > > > q;
	q.push({0,{s,t}});
	book[s][t] = 1;			//走过标记1
	while(!q.empty()){
		int x = q.top().second.first;
		int y = q.top().second.second;
		int step = q.top().first;
		q.pop();
		if(x == 0 && y == 0){
			cout<<step<<endl;
			return 0;
		}
		for(int i = 0; i < 4;i ++){
			int tx = x + dx[i];
			int ty = y + dy[i];
			if(tx >= 0 && tx <= 1003 && ty >= 0 && ty <= 1003 && book[tx][ty] == 0){
				book[tx][ty] = 1;
				if(vis[tx][ty])			如果格中有草,step+1;
					q.push({step+1,{tx,ty}});
				else
					q.push({step,{tx,ty}});
			}
		}
	}

    return 0;
}		
		

双端队列代码

#include<bits/stdc++.h>
#define ll long long
#define T int t;scanf("%d", &t);while(t--)
using namespace std;
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
const ll mod = 1e9+7;
const int maxn = 2e5+5;
int vis[1005][1005]={0};	//记录有没有草
int book[1005][1005]={0};	
int ans[1005][1005]={0};	//记录到一格要删去多少草
int n;
int s, t;
int main(){
	scanf("%d %d %d", &n, &s, &t);
	for(int i = 0; i < n; i++){
		int x,y;
		scanf("%d %d", &x, &y);
		vis[x][y] = 1;
	}
	deque<pair<int,int> > q;	
	q.push_back({s,t});
	book[s][t] = 1;
	while(!q.empty()){
		int x = q.front().first;
		int y = q.front().second;
		q.pop_front();
		if(x == 0 && y == 0){
			cout<<ans[0][0]<<endl;
			return 0;
		}
		for(int i = 0; i < 4;i ++){
			int tx = x + dx[i];
			int ty = y + dy[i];
			if(tx >= 0 && tx <= 1003 && ty >= 0 && ty <= 1003 && book[tx][ty] == 0){
				book[tx][ty] = 1;
				ans[tx][ty] = ans[x][y] + vis[tx][ty];	//更新要删草
				if(vis[tx][ty])
					q.push_back({tx,ty});	//如果有草,放到队尾搜
				else
					q.push_front({tx,ty});	//如果没草,放到队头搜
			}
		}
	}

    return 0;
}		
		
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值