带限制的广搜 codeforces
You are playing some computer game. One of its levels puts you in a maze consisting of n lines, each of which contains m cells. Each cell either is free or is occupied by an obstacle. The starting cell is in the row r and column c. In one step you can move one square up, left, down or right, if the target cell is not occupied by an obstacle. You can't move beyond the boundaries of the labyrinth.
Unfortunately, your keyboard is about to break, so you can move left no more than x times and move right no more than y times. There are no restrictions on the number of moves up and down since the keys used to move up and down are in perfect condition.
Now you would like to determine for each cell whether there exists a sequence of moves that will put you from the starting cell to this particular one. How many cells of the board have this property?
The first line contains two integers n, m (1 ≤ n, m ≤ 2000) — the number of rows and the number columns in the labyrinth respectively.
The second line contains two integers r, c (1 ≤ r ≤ n, 1 ≤ c ≤ m) — index of the row and index of the column that define the starting cell.
The third line contains two integers x, y (0 ≤ x, y ≤ 109) — the maximum allowed number of movements to the left and to the right respectively.
The next n lines describe the labyrinth. Each of them has length of m and consists only of symbols '.' and '*'. The j-th character of the i-th line corresponds to the cell of labyrinth at row i and column j. Symbol '.' denotes the free cell, while symbol '*' denotes the cell with an obstacle.
It is guaranteed, that the starting cell contains no obstacles.
Print exactly one integer — the number of cells in the labyrinth, which are reachable from starting cell, including the starting cell itself.
4 5
3 2
1 2
.....
.***.
...**
*....
10
4 4
2 2
0 1
....
..*.
....
....
7
Cells, reachable in the corresponding example, are marked with '+'.
First example:
+++..
+***.
+++**
*+++.
Second example:
.++.
.+*.
.++.
.++. 题意 : 给你一个n*m 的矩阵,再给你一个起点,你可以往上下左右四个方向走,但同时又有一个往左右的步数限制,询问所有可能到达的点数有多少个?
思路分析 :
比赛场上直接写了一个 bfs ,pp 了,自信以为A了,今晚又可以涨分,结果....
其实有一点贪心的想法,就是可以上下走的时候一定要先上下走,最后再左右走,用一个双端队列即可
代码示例:
int n, m;
int sx, sy;
int sl, sr; char mp[2005][2005];
struct node
{
int x, y;
int l, r;
};
deque<node>que;
bool vis[2005][2005]; int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; void bfs(){
que.push_front({sx, sy, sl, sr});
int ans = 0;
//vis[sx][sy] = 1; while(!que.empty()){
node v = que.front(); que.pop_front();
if (vis[v.x][v.y]) continue;
vis[v.x][v.y] = true;
ans++;
for(int i = 0; i < 4; i++){
int fx = v.x+dir[i][0];
int fy = v.y+dir[i][1];
if (fx < 1 || fx > n || fy < 1 || fy > m || mp[fx][fy] == '*'||vis[fx][fy]) continue; if (i == 2) {
if (v.r > 0) que.push_back({fx, fy, v.l, v.r-1});
}
else if (i == 3) {
if (v.l > 0) que.push_back({fx, fy, v.l-1, v.r});
}
else que.push_front({fx, fy, v.l, v.r});
}
}
printf("%d\n", ans);
} int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> n >> m;
cin >> sx >> sy;
cin >> sl >> sr;
for(int i = 1; i <= n; i++){
scanf("%s", mp[i]+1);
}
bfs();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(mp[i][j] == '*') printf("*");
else if (vis[i][j]) printf("+");
else printf(".");
}
printf("\n");
}
return 0;
}
2 . 用类似最短路的写法,每次左右走的时候步数+1,上下走的时候步数不变
代码示例:
const int inf = 0x3f3f3f3f; int n, m;
int sx, sy, sl, sr;
char mp[2005][2005];
struct node
{
int x, y;
int l, r;
int sum;
bool operator< (const node &v)const{
return sum < v.sum;
}
};
priority_queue<node>que;
bool vis[2005][2005];
int bu[2005][2005];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; void bfs() {
que.push({sx, sy, sl, sr, sl+sr});
memset(vis, false, sizeof(vis));
memset(bu, inf, sizeof(bu));
int ans = 0;
bu[sx][sy] = 0; while(!que.empty()){
node v = que.top(); que.pop(); if (!vis[v.x][v.y]) ans++;
vis[v.x][v.y] = 1;
for(int i = 0; i < 4; i++){
int fx = dir[i][0]+v.x;
int fy = dir[i][1]+v.y; if (fx < 1 || fx > n || fy < 1 || fy > m || mp[fx][fy] == '*') continue;
if (bu[v.x][v.y] >= bu[fx][fy]) continue;
bu[fx][fy] = bu[v.x][v.y]; if ((i == 2) || (i == 3)) bu[fx][fy]++;
if (i == 2) {
if (v.r) que.push({fx, fy, v.l, v.r-1, v.l+v.r-1});
}
else if (i == 3) {
if (v.l) que.push({fx, fy, v.l-1, v.r, v.l+v.r-1});
}
else que.push({fx, fy, v.l, v.r, v.l+v.r});
}
}
printf("%d\n", ans);
} int main() {
cin >> n >> m;
cin >> sx >> sy;
cin >> sl >> sr;
for(int i = 1; i <= n; i++) scanf("%s", mp[i]+1);
bfs();
return 0;
}
带限制的广搜 codeforces的更多相关文章
- HDU-1026 Ignatius and the Princess I(BFS) 带路径的广搜
此题需要时间更少,控制时间很要,这个题目要多多看, Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Me ...
- CodeForces 682C Alyona and the Tree(广搜 + 技巧)
方法:从根节点开始广搜,如果遇到了应该删除的点,就再广搜删掉它的子树并标记,然后统计一下被标记的个数就是答案,所谓技巧就是从根节点开始搜索的时候,如果遇到了某个节点的距离<0,就让它是0,0可以 ...
- Codeforces 1105D(双层广搜)
要点 题意:可以拐弯,即哈密顿距离 注意不可以直接一个一个搜,这过程中会把下一轮的标记上,导致同一轮的其它点没能正常完成应有的搜索 因此采用双层广搜,把同一轮先都出队列再的一起搜 #include & ...
- 『ice 离散化广搜』
ice(USACO) Description Bessie 在一个冰封的湖面上游泳,湖面可以表示为二维的平面,坐标范围是-1,000,000,000..1,000,000,000. 湖面上的N(1 & ...
- 队列&广搜
搜索里有深搜,又有广搜,而广搜的基础就是队列. 队列是一种特殊的线性表,只能在一段插入,另一端输出.输出的那一端叫做队头,输入的那一端叫队尾.是一种先进先出(FIFO)的数据结构. 正经的队列: 头文 ...
- HDU 1072 Nightmare (广搜)
题目链接 Problem Description Ignatius had a nightmare last night. He found himself in a labyrinth with a ...
- 用广搜实现的spfa
用广搜实现的spfa,如果是用一般的最短路,会发现构图很麻烦,因为它不是路径带权值,而是自身带权值.写起来只要注意,在点出队列的生活将其标记为0,在要压入队列的时候,判断其标记是否为0,为0表示队列中 ...
- CF520B——Two Buttons——————【广搜或找规律】
J - Two Buttons Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Su ...
- HDU--杭电--1195--Open the Lock--深搜--都用双向广搜,弱爆了,看题了没?语文没过关吧?暴力深搜难道我会害羞?
这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼? Open the Lock Time Limit: 2000/1000 MS (Java/Others) ...
随机推荐
- 从零开始学习Kafka
简介 kafka是一个分布式消息队列.具有高性能.持久化.多副本备份.横向扩展能力.生产者往队列里写消息,消费者从队列里取消息进行业务逻辑.一般在架构设计中起到解耦.削峰.异步处理的作用. Kafka ...
- 模版——KMP
#include <iostream> #include <cstdio> #include <cstring> ; int f[maxn]; char P[max ...
- linux 使用 /proc 文件系统
/proc 文件系统是一个特殊的软件创建的文件系统, 内核用来输出消息到外界. /proc 下 的每个文件都绑到一个内核函数上, 当文件被读的时候即时产生文件内容. 我们已经见到 一些这样的文件起作用 ...
- js中的克隆
1.如果克隆对象是基本类型,直接复制就可以 <script type="text/javascript"> var str1 = 'abc' var str2 = st ...
- js的cookie操作及知识点详解
<html> <head> <script type="text/javascript"> function getCookie(c_name) ...
- <mvc:annotation-driven /><context:annotation-config/><context:component-scan/>
<context:annotation-config/> 隐式地向 Spring容器注册AutowiredAnnotationBeanPostProcessor. RequiredAnno ...
- hdu 2454 Degree Sequence of Graph G(可简单图化判定)
传送门 •Havel-Hakimi定理: 给定一个非负整数序列{d1,d2,...dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化. 进一步,若图为简单图,则称此序列可简单图 ...
- Android studio相关设置及实现存在于工程目录中的视频播放
一:相关设置 1:主题设置 File-->Settings-->Appearance &Behavior-->Appearance-->THeme 2:Java源码的颜 ...
- $SCOI2009\ windy$数 数位$dp$
\(Sol\) 数位\(dp\)常规套路题. \(dp[i][j]\)表示从低位到高位填到第\(i\)位且第\(i\)位的数字为\(j\)的方案数.答案就是\(sol(r)-sol(l+1).\)这里 ...
- h5项目中关于ios手机软键盘导致页面变形的完美解决方案
1.项目背景:vue项目,手机加短信验证码登录: 2.问题: 在ios中input吊起软键盘,输入完成后,收起软件盘,页面不会回弹,导致页面下方出现空白,也就是页面变形: 3.最开始的解决方案是,用i ...