百练 4130 Saving Tang Monk [BFS+优先队列+状态压缩]

news/2024/11/1 22:37:50/


百练题目地址

判重3个状态就够了 位置+钥匙

除了#位置,其他位置都可以经过多次

注意钥匙数可以为零

因为打蛇要time+2,所以用优先队列

蛇的数量<=5,所以1<<5的数就足够保存蛇的状态了

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100+5;
int N,K,vis[maxn][maxn][10];   //判重三个状态表示就够了 
int r0,c0,r1,c1;
char G[maxn][maxn];
struct Point{int x,y,time,key,snack;Point(int x,int y,int t,int k,int s):x(x),y(y),time(t),key(k),snack(s){} bool operator < (const Point& p) const {return time>p.time;}
};
bool inside(int x,int y)
{return x>=0&&x<N&&y>=0&&y<N;
}
int bfs(int r,int c)
{priority_queue<Point> Q;Q.push(Point(r,c,0,0,0));vis[r][c][0]=1;while(!Q.empty()){int x=Q.top().x, y=Q.top().y, time=Q.top().time, key=Q.top().key, snack=Q.top().snack; Q.pop();if(key==K&&x==r1&&y==c1) return time;for(int dx=-1;dx<=1;dx++)for(int dy=-1;dy<=1;dy++){if((dx&&dy)||(!dx&&!dy)) continue;int nx=x+dx;int ny=y+dy;if(!inside(nx,ny)||G[nx][ny]=='#') continue;if(isalpha(G[nx][ny])){                        //遇到蛇判断是否曾经走过 bool killed=(1<<(G[nx][ny]-'A'))&snack;int ns=snack+(1<<(G[nx][ny]-'A'));if(killed&&!vis[nx][ny][key]) {Q.push(Point(nx,ny,time+1,key,snack));vis[nx][ny][key]=1;}else if(!killed&&!vis[nx][ny][key]) {vis[nx][ny][key]=1;Q.push(Point(nx,ny,time+2,key,ns));}}else {if(!vis[nx][ny][key]) {      //除了蛇之外都可以走 vis[nx][ny][key]=1;Q.push(Point(nx,ny,time+1,key,snack));}if(isdigit(G[nx][ny])){  //拿钥匙 int nkey=G[nx][ny]-'0';if(nkey==key+1&&!vis[nx][ny][nkey]){Q.push(Point(nx,ny,time+1,nkey,snack));vis[nx][ny][nkey]=1;}}	}}}return -1;
}
int main()
{while(scanf("%d%d",&N,&K)==2&&N)  //K可以等于0 {int cnt=0;for(int i=0;i<N;i++)for(int j=0;j<N;j++){cin>>G[i][j];if(G[i][j]=='K') r0=i,c0=j,G[i][j]='.';else if(G[i][j]=='T') r1=i,c1=j,G[i][j]='.';else if(G[i][j]=='S') G[i][j]='A'+cnt++;   //给蛇编号 }memset(vis,0,sizeof(vis));int ans=bfs(r0,c0);if(ans==-1) cout<<"impossible"<<endl;else cout<<ans<<endl;}return 0;
}



http://www.ppmy.cn/news/221964.html

相关文章

【BZOJ】4130: [PA2011]Kangaroos【KD树——最长连续1的子段长度】

传送门&#xff1a;【BZOJ】4130: [PA2011]Kangaroos【KD树】 题意&#xff1a;给出一个长度为 N(N≤5⋅104) 的区间序列。然后接下来 M(M≤2⋅105) 个询问&#xff0c;每个询问给出一个区间 [L,R] &#xff0c;问区间序列中最长的连续子序列长度&#xff0c;使得连续子序列中…

Rimini Street接到法院命令,将获得甲骨文2150万美元退款,还将寻求通过进一步上诉获得额外的4130万美元

法院宣布Rimini Street在与甲骨文直接维护服务合法竞争状态下提供第三方支持 拉斯维加斯--(美国商业资讯)--Rimini Street, Inc. (Nasdaq: RMNI)是企业软件产品和服务的全球供应商以及甲骨文和SAP软件产品的领先第三方支持提供商&#xff0c;今天发布如下与甲骨文对Rimini Stre…

​支持AS2协议的开源的软件MTTK_AS2发布 [AS2] | [RFC4130] | [EDI] | [ANSI X12] | [EDIFACT]

​支持AS2协议的开源的软件MTTK_AS2发布 固执的可乐瓶 小型收发报文工具如何实现AS2协议&#xff1f;MTTK_AS2开源产品推荐 许多中小型企业 在与国外的系统进行数据传输时&#xff0c;通常会被要求使用AS2协议进行报文的传输&#xff0c;而国内对于AS2协议支持的开源软件少之…

ITS4130Q-EP-D是一款130mΩ四通道智能高压侧电源开关——科时进商城

​ 四个通道的电流均大于500 mA&#xff0c;Tj125C时的典型RDS&#xff08;ON&#xff09;值非常低&#xff0c;为205mΩ&#xff0c;以及小型PG-TSDSO-14外露焊盘封装&#xff0c;将高灵活性与最低空间要求结合在一起。热增强PG-TSDSO-14封装的外露焊盘允许通过热通孔从器件到…

百炼 4130: Saving Tang Monk

同一个S可能需要多次经过&#xff0c;只需杀一次。 #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<algorithm> #include<queue> using namespace std;const int N 100 5;char s[N][N]; int si, sj, n, m, ei, ej, p[N][N];struct Node {int…

【JZOJ1214】【洛谷P4130】项链工厂【线段树】

题目大意&#xff1a; 题目链接&#xff1a;https://www.luogu.org/problemnew/show/P4130 一条项链包含 N 个珠子&#xff0c;每个珠子的颜色是 1&#xff0c;2&#xff0c;…&#xff0c;c 中的一种。项链 被固定在一个平板上&#xff0c;平板的某个位置被标记位置 1 &…

百炼4116 拯救行动4130 Saving Tang Monk4115 鸣人与佐助 简单BFS搜索题型总结对比

一、 百炼4116拯救行动&#xff08;OpenJudge - 4116:拯救行动&#xff09; 这题就是在简单BFS的基础上加了一个守卫&#xff0c;击杀一次守卫时间也需要1&#xff0c;其他照常按照普通BFS的思路就行&#xff0c;最主要就是可以把击杀守卫看成是经过两次这一个点&#xff0c;这…

BZOJ4130:[PA2011]Kangaroos

浅谈\(K-D\ Tree\)&#xff1a;https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门&#xff1a;https://lydsy.com/JudgeOnline/problem.php?id4130 这题跟\(BZOJ4358:permu\)一样。 不过我们需要把区间包含某个点改成判断区间是否有交点。 假设我们有俩区间\([l,r]\)…