NYOJ - 1100 - WAJUEJI which home strong!(BFS变形,优先队列)

输入
第一个数T,T组测试数据。
两个数 n, m; ( 0< n , m <= 100 ) 表示一个h行m列的二维地图。
接下来n行每行m 个字符。
‘s’ 表示弟弟目前所在位置。
‘# ’表示此处为一座山。为了节省体力,不从此处通行。
从‘A’-‘Z’表示各地的经济水平,对应1-26,路过对应字符的地区需要交对应的生活费。
‘l’表示蓝翔技校的所在地。
s 与 l 均为小写字母。
弟弟只能走四个方向。
输出
输出一个数表示弟弟到达蓝翔需要的生活费最小是多少。
如果不能到达,输出 -1。
样例输入
3
3 5
#sVGF
A##ZA
lCDBC
3 3
sAB
ABS
ABl
3 3
s#B
###
ABl

样例输出

48
4
-1


题目大概意思是,给定一个n*m的图,s点的位置表示起点,l(小写字母L)点的位置表示重点的位置,其中#表示无法走的,ABCD....Z分别表示城市,并且分别对应(1~26)表示经过城市所需要的花费。现在要求从起点到重点所需要花费的最少费用是多少,如果无法到达输出-1。

思路:提到最短路径,首先想到的是bfs,但是这道题是要求最少的花费,花费最少时,不一定就是最短路。比如说

#####
#sZl#
#AAA#
#####
从s到l的最少步数是2 但是花费是26,而最少花费是3,但是步数是4。那么想要利用bfs找到最少的花费应该怎么做。

这里我用了优先队列,重载运算符后。在出队的时候,花费最少的先出队,即,优先从花费最少的地方搜索。从s先搜索,<(0,0)花费0>  入队,搜索后<(0,1)花费26> 和<(1,0)花费1 >入队,因为花费少的优先出队,所以从(1,0)开始搜索,<(1,2)花费2>入队,同理<(1,3)花费3>入队,在(1,3)搜索时,搜到重点l,退出搜索,输出结果。

struct Point{
	int x,y,money;
	//重载小于运算符  
	friend  bool operator<(Point a,Point b){
		//money小的优先出队 
		return a.money>b.money; 
	}
};

完整AC代码:


#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
struct Point{
	int x,y,money;
	//重载小于运算符  
	friend  bool operator<(Point a,Point b){
		//money小的优先出队 
		return a.money>b.money; 
	}
};


char map[105][105];
int vis[105][105];
int dir[4][2] = {0,1 ,0,-1 ,1,0 ,-1,0};
int x1,y1,x2,y2,ans,n,m,t;

void bfs(){
	if(x1==x2&&y1==y2){
		ans = 0;
		return ;
	}
	priority_queue<Point>q;//优先队列 money越小越好 
	Point v1;
	v1.x = x1;
	v1.y = y1;
	v1.money = 0;
	vis[x1][y1] = 1;
	q.push(v1);
	
	while(!q.empty()){
		Point v2;
		for(int i=0 ;i<4 ;i++){
			v2.x = q.top().x + dir[i][0];
			v2.y = q.top().y + dir[i][1];
			if(v2.x>=0&&v2.x<n&&v2.y>=0&&v2.y<m&&!vis[v2.x][v2.y]&&map[v2.x][v2.y]!='#'){
				if(v2.x==x2&&v2.y==y2){
					ans = q.top().money;
					break;
				}
				v2.money = q.top().money + (int)(map[v2.x][v2.y]-'A'+1);
				vis[v2.x][v2.y] = 1;
				q.push(v2);
				
			}
		}
		if(v2.x==x2&&v2.y==y2){
			return ;
		}
		q.pop();
	}
	
}

int main(){
	scanf("%d",&t);
	while(t--){
		memset(vis,0,sizeof(vis));
		ans = -1;
		scanf("%d%d",&n,&m);
		
		getchar();
		for(int i=0 ;i<n ;i++){
			gets(map[i]);
		}
		for(int i=0 ;i<n ;i++){
			for(int j=0 ;j<m ;j++){
				if(map[i][j]=='s'){
					x1 = i;
					y1 = j;
				}
				if(map[i][j]=='l'){
					x2 = i;
					y2 = j;
				}
			}
		}
		bfs();
		printf("%d\n",ans);
	}
	
	return 0;
}




孪生素是指两个素之间的差值为2的素对。通过筛选法可以找出给定素范围内的所有孪生素的组。 在引用的代码中,使用了递归筛选法来解决孪生素问题。该程序首先使用循环将素的倍标记为非素,然后再遍历素组,找出相邻素之间差值为2的素对,并统计总。 具体实现过程如下: 1. 定义一个组a[N,用来标记字是否为素,其中N为素范围的上限。 2. 初始化组a,将0和1标记为非素。 3. 输入要查询的孪生素的个n。 4. 循环n次,每次读入一个要查询的素范围num。 5. 使用两层循环,外层循环从2遍历到num/2,内层循环从i的平方开始,将素的倍标记为非素。 6. 再次循环遍历素组,找出相邻素之间差值为2的素对,并统计总。 7. 输出。 至此,我们可以使用这个筛选法的程序来解决孪生素问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python用递归筛选法求N以内的孪生质(孪生素)](https://blog.csdn.net/weixin_39734646/article/details/110990629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [NYOJ-26 孪生素问题](https://blog.csdn.net/memoryofyck/article/details/52059096)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值