P6474

摘自:
一看题目,像个搜索
再一看,像个广度优先搜索
既然是BFS,那我们首先要搞出一个(一堆)队列
那问题是队列里咱们存啥呢???
首先,按照广搜解决“迷宫问题”的国际惯例,肯定要先把坐标和步数存到里面!
可是,这似乎不大够?
因为荆轲还有两种技能:隐身和瞬移。
隐身:balabala……
瞬移:balabala……
现在给出咸阳城的地图,请计算荆轲到达秦王所在点所需的最短时间。此外,在所用时间相同情况下,荆轲希望使用的两种技能总次数尽可能少;在所用时间与技能次数相同情况下,荆轲希望使用的隐身次数尽可能少。
emmmmm,还要把隐身和瞬移的使用次数存下来~
啊,要存这么多东西……这时候,结构体就要派上用场啦!

struct qwq{
	int x,y,yx,sy,s;
	//x,y——对应的坐标
	//s——走到这一步的步数
	//yx——隐形使用次数
	//sy——瞬移使用次数
	//(都是用拼音写的呢)
};
queue <qwq> q;

当然,我们要在茫茫多的方案中选择一个最优解——所以,我们要写一个函数(算是取min吧……),来选择一个最优解

qwq minq(qwq a,qwq b){
	if(a.s!=b.s)return a.s<b.s?a:b;//优先选择步数更小的
	if(a.yx+a.sy!=b.yx+b.sy)return a.yx+a.sy<b.yx+b.sy?a:b;//如果步数相等,选择一个技能使用更少的
	return a.yx<b.yx?a:b;//都相等?!那就选一个隐身用的更少的吧
}
qwq ans=(qwq){0,0,233333333,233333333,233333333};//顺便把初始化的ans放出来,当然要挑个大的

……

#include<bits/stdc++.h>
using namespace std;
struct qwq{
	int x,y,yx,sy,s;
};
qwq minq(qwq a,qwq b){
	if(a.s!=b.s)return a.s<b.s?a:b;
	if(a.yx+a.sy!=b.yx+b.sy)return a.yx+a.sy<b.yx+b.sy?a:b;
	return a.yx<b.yx?a:b;
}
bool vis[355][355][20][20],look[355][355];
int tag[355][355];
int n,m,c1,c2,d;
int map[355][355];
const int dx[8]={1,0,-1,0,1,-1,-1,1},dy[8]={0,1,0,-1,1,1,-1,-1};
void lookaround(int x,int y,int k){
	for(int i=0;i<=k;i++){
		tag[max(x-i,1)][max(y-(k-i),1)]++; 
		tag[max(x-i,1)][min(y+(k-i),m)+1]--;
		tag[min(x+i,n)][max(y-(k-i),1)]++;
		tag[min(x+i,n)][min(y+(k-i),m)+1]--;
	}
}
int sx,sy,ex,ey;
queue <qwq> q;
qwq ans=(qwq){0,0,233333333,233333333,233333333};
void bfs(){
	while(!q.empty()){
		qwq fro=q.front();
		q.pop();
		if(fro.s>ans.s)continue;
		if(fro.x==ex&&fro.y==ey){
			ans=minq(ans,fro);
			continue;
		} 
		for(int i=0;i<8;i++){
			int nx=fro.x+dx[i];
			int ny=fro.y+dy[i];
			if(nx<1||nx>n||ny<1||ny>m||map[nx][ny]>0)continue;
			if(look[nx][ny]){
				if(vis[nx][ny][fro.yx+1][fro.sy]||fro.yx+1>c1)continue;
				vis[nx][ny][fro.yx+1][fro.sy]=1;
				q.push((qwq){nx,ny,fro.yx+1,fro.sy,fro.s+1});
			}
			else{
				if(vis[nx][ny][fro.yx][fro.sy])continue;
				vis[nx][ny][fro.yx][fro.sy]=1;
				q.push((qwq){nx,ny,fro.yx,fro.sy,fro.s+1});				
			}
		}
		if(fro.sy+1>c2)continue;
		for(int i=0;i<4;i++){
			int nx=fro.x+dx[i]*d;
			int ny=fro.y+dy[i]*d;
			if(nx<1||nx>n||ny<1||ny>m||map[nx][ny]>0)continue;
			if(look[nx][ny]){
				if(vis[nx][ny][fro.yx+1][fro.sy+1]||fro.yx+1>c1)continue;
				vis[nx][ny][fro.yx+1][fro.sy+1]=1;
				q.push((qwq){nx,ny,fro.yx+1,fro.sy+1,fro.s+1});
			}
			else{
				if(vis[nx][ny][fro.yx][fro.sy+1])continue;
				vis[nx][ny][fro.yx][fro.sy+1]=1;
				q.push((qwq){nx,ny,fro.yx,fro.sy+1,fro.s+1});				
			}			
		}
	}
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n>>m>>c1>>c2>>d;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			string s;
			cin>>s;
			if(s[0]=='S'){
				sx=i,sy=j;
				map[i][j]=-1;
				q.push((qwq){sx,sy,0,0,0});
				vis[i][j][0][0]=1;
			}
			else if(s[0]=='T'){
				ex=i,ey=j;
				map[i][j]=-2;
			}
			else if(s[0]=='.')map[i][j]=0;
			else{
				int x=0;
				for(int i=0;i<s.size();i++)
				x=(x<<1)+(x<<3)+(s[i]^'0');
				map[i][j]=x;
				lookaround(i,j,x-1);
			}
		}
	}
	for(int i=1;i<=n;i++){
		int sum=0;
		for(int j=1;j<=m;j++){
			sum+=tag[i][j];	
			if(sum>0)look[i][j]=1;	
		}
	}	
	bfs();
	if(ans.s==233333333)printf("-1");
	else printf("%d %d %d",ans.s,ans.yx,ans.sy);
	return 0;
}
posted @ 2024-09-18 19:58  yzc_is_SadBee  阅读(6)  评论(0编辑  收藏  举报