清北学堂模拟赛d6t6 棋盘迷宫
3.棋盘迷宫
(boardgame.pas/c/cpp)
(boardgame.in/out)
时间限制:5s/空间限制:256M
【题目描述】
小 A 和小 Z 是非常要好的朋友, 而且他们都对迷宫游戏非常有兴趣。 他们经
常在自习课上用迷宫来打发时间(两位都是学习效率 400%的 dalao, 大家切记不
要模仿) 。
他们的迷宫非常简单, 又被他们叫做是棋盘迷宫, 迷宫本身是一个 N*M 大小
的棋盘, 从左往右列数不断加大, 从上往下行数不断增大, 故左上角的坐标为(1,
1),右下角的坐标为(N,M) 。 当你处在坐标为(X,Y) 的格子里时, 你只能走到
(X+1,Y) 或(X,Y+1) , 即只能往右走或者往下走(当然你也不能走出棋盘) 。
同时部分格子中有障碍物, 这样的格子是不能经过的, 用‘#’ 代表, 能正常通
行的格子由‘.’ 代表。
每一轮游戏先由其中一人选定起点和终点, 由另外一个人来完成) 。 但是他
们很快发现, 并不是每次都能找到一条从起点到达终点的路径, 两位 dalao 的注
意力立刻从游戏转移到了如何快速判断路径是否存在这个问题上。
当然 dalao 们瞬间得到了算法, 不过他想考考你, 如果你能顺利解决, 也许
就能得到他们两个的签名哦! (据说是最高级别的因果律护身符, 能让人逢考必
过)
【输入格式】 (boardgame.in)
一共 N Q 2 行。
第一行两个正整数为 N, M , 表示棋盘迷宫的行列。
接下来 N 行, 每行一个长度为 M 的字符串, 由‘#’ ‘.’ 两种字符组成
接下来 1 行, 一个正整数 Q ,表示询问的个数
接下来 Q 行, 每行四个正整数 x1,y1,x2,y2 询问点(x1,y1) 到(x2,y2) 是
否有一条合法的路径
数据保证(x1,y1) (x2,y2) 所在的位置都是‘.’ , 同时 x1<=x2,y1<=y2
【输出格式】 (boardgame.out)
一共 Q 行, 每行一个字符串Yes 或者 No , 对应每一个询问的答案。

分析:思路比较新奇的一道题。在线做是做不到满分的,只有离线了看看多组询问有什么特征.如果询问点对一个点在图的上半部分,一个点在图的下半部分,那么它们之间的路径肯定要经过中间.考虑一个类似meet in the middle的思想,我们从中间那条线上的点分别向上和向下延伸,看看它能到达哪些点,这样就能处理点对上的点分布在上下两个半图的情况,如果不在同一半图怎么办呢?分治递归就可以了.因为最后点对的两个点肯定要经过中间这条线上的同一个点,所以我们记录f[i][j][k]来表示(i,j)能够到达中间线上的哪些点(k是状态),最后利用二进制处理一下就好了.标程用了bitset,学了一下,似乎挺好用的.
超多组询问问题我人为要么就是预处理一下,要么就是询问之间肯定有公共类似的部分,从这个公共部分出发,就能通过枚举少数解得到多数解.
#include <cstdio>
#include <bitset>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int n, m, q, flag[];
char s[][];
bitset <> f[][], g[][]; struct node
{
int x1, y1, x2, y2, id;
}; void dfs(vector <node> v, int l, int r)
{
if (l > r)
return;
int mid = (l + r) >> ;
for (int i = mid; i >= l; i--) //从合法状态扩展到合法状态,必须倒着枚举
for (int j = m; j >= ; j--)
{
f[i][j] = ;
if (s[i][j] == '.')
{
if (i == mid)
f[i][j].set(j);
else
f[i][j] |= f[i + ][j];
if (j != m)
f[i][j] |= f[i][j + ];
}
}
for (int i = mid; i <= r; i++)
for (int j = ; j <= m; j++)
{
g[i][j] = ;
if (s[i][j] == '.')
{
if (i == mid)
g[i][j].set(j);
else
g[i][j] |= g[i - ][j];
if (j != )
g[i][j] |= g[i][j - ];
}
}
vector <node> vl, vr;
for (vector <node>::iterator it = v.begin(); it != v.end(); it++)
{
node q = *it;
if (q.x2 < mid)
vl.push_back(q);
else
if (q.x1 > mid)
vr.push_back(q);
else
flag[q.id] = (f[q.x1][q.y1] & g[q.x2][q.y2]).any();
}
dfs(vl, l, mid - );
dfs(vr, mid + , r);
} int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%s", s[i] + );
vector <node> v;
scanf("%d", &q);
for (int i = ; i <= q; i++)
{
node temp;
scanf("%d%d%d%d", &temp.x1, &temp.y1, &temp.x2, &temp.y2);
temp.id = i;
v.push_back(temp);
}
dfs(v, , n);
for (int i = ; i <= q; i++)
{
if (flag[i])
printf("Yes\n");
else
printf("No\n");
} return ;
}
清北学堂模拟赛d6t6 棋盘迷宫的更多相关文章
- 清北学堂模拟赛day7 数字碰撞
/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...
- 清北学堂模拟赛d4t1 a
分析:大模拟,没什么好说的.我在考场上犯了一个超级低级的错误:while (scanf("%s",s + 1)),导致了死循环,血的教训啊,以后要记住了. /* 1.没有发生改变, ...
- 清北学堂模拟赛day7 错排问题
/* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...
- 清北学堂模拟赛day7 石子合并加强版
/* 注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化 */ #include<iostream> #include<cstdio&g ...
- 清北学堂模拟赛d1t2 火柴棒 (stick)
题目描述众所周知的是,火柴棒可以拼成各种各样的数字.具体可以看下图: 通过2根火柴棒可以拼出数字“1”,通过5根火柴棒可以拼出数字“2”,以此类推. 现在LYK拥有k根火柴棒,它想将这k根火柴棒恰好用 ...
- 清北学堂模拟赛d1t1 位运算1(bit)
题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值.假设数字N的价值是K,LYK想找到一个 ...
- 清北学堂模拟赛d2t6 分糖果(candy)
题目描述总共有n颗糖果,有3个小朋友分别叫做L,Y,K.每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感.也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果 ...
- 清北学堂模拟赛d2t5 吃东西(eat)
题目描述一个神秘的村庄里有4家美食店.这四家店分别有A,B,C,D种不同的美食.LYK想在每一家店都吃其中一种美食.每种美食需要吃的时间可能是不一样的.现在给定第1家店A种不同的美食所需要吃的时间a1 ...
- 清北学堂模拟赛d2t4 最大值(max)
题目描述LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目:这里有一个长度为n的正整数数列ai(下标为1~n).并且有一个参数k.你需要找两个正整数x,y,使得x+k<=y, ...
随机推荐
- [Clr via C#读书笔记]Cp11事件
Cp11事件 类型之所以提供事件通知功能,是因为类型维护了一个已登记方法的列表,事件发生后,类型将通知列表登记的所有方法: 事件模型建立在委托的基础上.委托是调用回调方法的一种类型安全的方式. 设计事 ...
- cenos环境变量配置
Beego环境搭建和bee工具安装使用,以Windows环境为例. 首先,下载并安装好GO并配置好GOROOT和GOPATH环境变量(如果您是用msi包安装的go,那么这些环境变量已经设置好了).并在 ...
- BZOJ 4736 温暖会指引我们前行 LCT+最优生成树+并查集
题目链接:http://uoj.ac/problem/274 题意概述: 没什么好概述的......概述了题意就知道怎么做了......我懒嘛 分析: 就是用lct维护最大生成树. 然后如果去UOJ上 ...
- Python中的名字隐藏
Python对于module文件中的name是没有private和public区分的,严格来说,在module文件重定义的任何name,都可以被外界访问.但是,对于 from module imort ...
- Beta阶段项目展示博客
Beta阶段项目展示 团队成员的简介 详细见团队简介 角色 姓名 照片 项目经理,策划 游心 策划 王子铭 策划 蔡帜 美工 赵晓宇 美工 王辰昱 开发.架构师 解小锐 开发 陈鑫 开发 李金奇 开发 ...
- Android开发随笔5
昨天: 对界面的进一步设计补充 可以在界面之间的跳转 研究了对图标等的操作 今天: 实现对库的相关操作 学习视视频内容‘ 复习java的一些知识.
- Python 服务器端表单验证插件
Python格式验证库 Cerberus 作者 MrStranger 关注 2016.08.02 14:44 字数 2140 阅读 79评论 0喜欢 1 Cerberus是一个验证Python对象.M ...
- object-oriented 第二次作业(2)
面向对象程序设计自学计划 由于我的英文实在是很差,所以我就没有去考虑看英文的课程视频.网络上的课程有很多,什么学校的也有,一开始我不知道该如何开始选择课程.感觉每个都还可以.后来在群里的看到别人推荐的 ...
- lintcode-189-丢失的第一个正整数
189-丢失的第一个正整数 给出一个无序的正数数组,找出其中没有出现的最小正整数. 样例 如果给出 [1,2,0], return 3 如果给出 [3,4,-1,1], return 2 挑战 只允许 ...
- C# HttpWebRequest post提交数据,提交对象
1.客户端方法 //属于客户端 //要向URL Post的方法 public void PostResponse() { HttpWebRequest req = (HttpWebRequest)Ht ...