位运算标记+BFS无输出结果求助
查看原帖
位运算标记+BFS无输出结果求助
592126
13402805827wuaiyang楼主2023/1/11 22:03

记录

代码:

//总体思路:1.位运算求出在不同体积下可以到的地方
//			2. BFS,在碰到在当前体积已经遍历过的点时,将其体积更新时的下一步放入优先队列 
#include <bits/stdc++.h>
using namespace std;
char mp[305][305];
bitset<305> bit[5][305];
int n,k,nx[4]={0,1,0,-1},ny[4]={1,0,-1,0};
int bjt[305][305][5],flag;
struct T{
	int x,y,tim,bj;
	bool operator <(const T temp)const{
		return tim>temp.tim;
	} 
};
priority_queue<T> que;
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>mp[i][j];
	
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)	if(mp[i][j]=='*') bit[0][i][j]=1;//本身为1 
	
	for(int i=0;i<=n+1;i++) bit[0][i][0]=bit[0][0][i]=bit[0][n+1][i]=bit[0][i][n+1]=1;//边界预处理 
	
	for(int i=0;i<=n+1;i++) bit[1][i]=(bit[0][i])|(bit[0][i]<<1)|(bit[0][i]>>1);//同一层连续3个(左右和自己)是否有1 
	
	for(int i=1;i<=n;i++) bit[2][i]=(bit[1][i]|bit[1][i-1]|bit[1][i+1]);//上一层,本层,下一层(3*3方阵) 是否有1
	
	bit[2][0]=bit[1][0];bit[2][n+1]=bit[1][n+1];//边界继承 
	
	for(int i=0;i<=n+1;i++) bit[3][i]=(bit[2][i]<<1)|(bit[2][i]>>1);//左右3*3方阵(3*5方阵)是否有1 
	
	for(int i=1;i<=n;i++) bit[4][i]=bit[3][i-1]|bit[3][i+1];//上下3*5方阵(5*5方阵) 是否有1 
	
	bit[4][0]=bit[3][0];bit[4][n+1]=bit[3][n+1];
	
	 //位运算得到在不同体积下可以移动到哪些地方(1代表不能被移动到) 
//	for(int i=0;i<=n+1;i++) cout<<bit[4][i]<<endl;
	que.push((T){3,3,0,4});
	while(!que.empty()){
		T ls=que.top();que.pop();
		if(ls.tim>2*k) ls.bj=0;
		else if(ls.tim>k) ls.bj=2;//更新体积 
		if(bit[ls.bj][ls.x][ls.y]) continue;
		if(bjt[ls.x][ls.y][ls.bj]){//如果已经在当前体积被遍历,让其原地等待到体积更新 
			if(bjt[ls.x][ls.y][ls.bj]==1){//没有已经原地等待的元素 
				bjt[ls.x][ls.y][ls.bj]=2;//标记 
				if(ls.bj!=0){
					ls.tim=(ls.tim/k+1)*k+1;//在时间更新的基础上再加一步(否则体积无法被更新) 
					ls.bj-=2;
					for(int i=0;i<4;i++){
						int tmpx=ls.x+nx[i],tmpy=ls.y+ny[i];
						if(tmpx-ls.bj/2<1||tmpy-ls.bj/2<1||tmpx+ls.bj/2>n||tmpy+ls.bj/2>n) continue;
						que.push((T){tmpx,tmpy,ls.tim,ls.bj});
					}
				}
			}
			continue;
		}
		
		bjt[ls.x][ls.y][ls.bj]=1;
		if(ls.x==n-2&&ls.y==n-2){
			printf("%d",ls.tim);
			return 0;
		}
		
		ls.tim+=1;
		if(ls.tim>2*k) ls.bj=0;
		else if(ls.tim>k) ls.bj=2;
		for(int i=0;i<4;i++){
			int tmpx=ls.x+nx[i],tmpy=ls.y+ny[i];
			if(tmpx-ls.bj/2<1||tmpy-ls.bj/2<1||tmpx+ls.bj/2>n||tmpy+ls.bj/2>n) continue;
			que.push((T){tmpx,tmpy,ls.tim,ls.bj});
		}//正常拓展 
	}
	return 0;
}
2023/1/11 22:03
加载中...