AcWing 172. 立体推箱子 BFS+状态表示

2023-11-10


代码参考了书上的。判断是否合法的函数写的好精简!

这题理解了,就能很好的理解BFS。

状态表示的理解:

//lie==0 立着 lie==1 横着躺着  lie==2 竖着躺着
//j:0123分别表示左右上下
//nextx[i][j]代表lie==i时x往j方向走的变化
const int nextx[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
const int nexty[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
const int nextlie[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}};

比如:
立着时想往左走,即[0][0],走法就是变成横躺,左上角的坐标:行不变,列-2。
因此:
nextx[0][2]=0;//行不变即x不变
nexty[0][2]=-2;//列-2即对应的值为-2
nextlie[0][2]=1;//1表示横躺
正好对应。

总代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define pb push_back
#define fi first
#define se second
#define mem(a,x) memset(a,x,sizeof(a));
#define db double 
#define fir(i,a,n) for(int i=a;i<=n;i++)
#define debug(x) cout<<#x<<" "<<x<<endl;
const int inf=0x3f3f3f3f;
const int MOD=1e9+7;
//书上代码写的太好了 所以对着打一打======================
const int N=550;
char g[N][N];
int d[N][N][3];
struct node
{
	int x,y,lie;
};
node s,e;
queue<node>q;
int n,m;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void startandend()
{
	for(int i=1;i<=n;i++) scanf("%s",g[i]+1);
	
	int flag=0;
	fir(i,1,n)
		fir(j,1,m)
		{
			if(g[i][j]=='O') 
			{
				e.x=i,e.y=j,e.lie=0;
				g[i][j]='.';
				flag++;
			}
			else if(g[i][j]=='X')
			{
				int x1=i,y1=j;
				int x2=i,y2=j;
				g[i][j]='.';
				flag++;
				s={x1,y1,0};
				for(int k=0;k<4;k++)
				{
					if(g[i+dx[k]][j+dy[k]]=='X')
					{
						x2=i+dx[k];
						y2=j+dy[k];
						g[x2][y2]='.';						
						if(x1==x2)//heng
						{
							y1=min(y1,y2);
							s={x1,y1,1};
						}
						else
						{
							x1=min(x1,x2);
							s={x1,y1,2};
						}						
						break;
					}
				}							
			}
			if(flag==2) break;	
		}				
}

int judge_fw(int x,int y)
{
	return x>=1&&x<=n&&y>=1&&y<=m;
}
int judge(node t)
{
	if(!judge_fw(t.x,t.y)) return 0;
	if(g[t.x][t.y]=='#') return 0;
	
	if(t.lie==0&&g[t.x][t.y]!='.') return 0;
	if(t.lie==1&&g[t.x][t.y+1]=='#') return 0;
	if(t.lie==2&&g[t.x+1][t.y]=='#') return 0;
	
	return 1;
}
const int nextx[3][4]={{0,0,-2,1},{0,0,-1,1},{0,0,-1,2}};
const int nexty[3][4]={{-2,1,0,0},{-1,2,0,0},{-1,1,0,0}};
const int nextlie[3][4]={{1,1,2,2},{0,0,1,1},{2,2,0,0}};
void bfs()
{
	while(q.size()) q.pop();//clear
	
	fir(i,1,n)
		fir(j,1,m)
			for(int k=0;k<3;k++)
			{
				d[i][j][k]=-1;
			}
	
	d[s.x][s.y][s.lie]=0;
	q.push(s);
	while(q.size())
	{
		node now=q.front();
		q.pop();
		
		for(int i=0;i<4;i++)
		{
			node next={now.x+nextx[now.lie][i],now.y+nexty[now.lie][i],nextlie[now.lie][i]};
			if(!judge(next)) continue;
			
			if(d[next.x][next.y][next.lie]==-1)
			{
				d[next.x][next.y][next.lie]=d[now.x][now.y][now.lie]+1;
				q.push(next);
			}
		}
	}
}
int main()
{
	while(cin>>n>>m&&n&&m)
	{
		startandend();
		bfs();
		if(d[e.x][e.y][e.lie]==-1) cout<<"Impossible";
		else cout<<d[e.x][e.y][e.lie];
		cout<<endl;
	}		
	return 0; 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AcWing 172. 立体推箱子 BFS+状态表示 的相关文章

  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 私有模板函数

    我有一堂课 C h class C private template
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col

随机推荐