CF540C Ice Cave 解题报告
1 题目链接
http://codeforces.com/contest/540/problem/C
2 题目整理
2.1 题目 : 冰洞
2.2 题目描述
你玩电脑游戏。你的角色站在一个多层次的冰洞的某个层次上。为了继续前进,你需要下降一层,唯一的方法就是从冰上掉下来。
你所在的洞穴层级是一个n行m列的矩形方格。每个细胞要么由完整的冰组成,要么由破裂的冰组成。您可以从每个单元格移动到与您的单元格相邻的单元格(由于游戏引擎的某些限制,您不能在同一个地方进行跳跃,即从一个单元格跳到它自己)。如果你移动到破裂的冰块,那么你的角色会从里面掉下来,如果你移动到完整的冰块,那么这个冰块上的冰就会裂开。
让我们从上到下用从1到n的整数对行进行编号,从左到右用从1到m的整数对列进行编号。让我们将第r行和第c列的交叉点上的单元格表示为(r,c)。
你待在(r1, c1)这个冰块上,这个冰块破裂了,因为你刚刚从更高的层次跌落到这里。您需要从牢房(r2, c2)中跌落,因为那里有通往下一层的出口。你能做这个吗?
2.3 输入格式
第一行包含两个整数n和m — 洞穴描述中的行数和列数。
接下来的n行中的每一行都描述了洞穴层的初始状态,每行由m个字符“ . ”(即完整的冰)和“ X ”(破裂的冰)组成。
下一行包含两个整数,r1和c1 —— 你的初始坐标。保证洞穴的描述在单元格(r1,? c1)中包含字符’ X ’ ,即起始单元格上的冰最初是破裂的。
下一行包含两个整数r2和c2 ——你需要穿过的单元格的坐标。最后的单元格可能与开始的单元格重合。
2.4 输出格式
如果可以到达目的地,打印’ YES ‘,否则打印’ NO '。
2.5.1 样例输入1
4 6
X...XX
...XX.
.X..X.
......
1 6
2 2
2.5.2 样例输出1
YES
2.6.1 样例输入2
5 4
.X..
...X
X.X.
....
.XX.
5 3
1 1
2.6.2 样例输出2
NO
2.7.1 样例输入3
4 7
..X.XX.
.XX..X.
X...X..
X......
2 2
1 6
2.7.2 样例输出3
YES
2.8 数据范围
对于
100
%
100\%
100%的数据:
1
≤
n
,
m
≤
500
1 \le n,m \le 500
1≤n,m≤500
1
≤
r
1
≤
n
,
1
≤
c
1
≤
m
1 \le r_1 \le n,1 \le c_1 \le m
1≤r1≤n,1≤c1≤m
1
≤
r
2
≤
n
,
1
≤
c
2
≤
m
1 \le r_2 \le n,1\le c_2 \le m
1≤r2≤n,1≤c2≤m
3 题意分析
3.1 题目大意
给你一个地图,开始你在(r1,c1)上,不能走到’X’上,且(r2,c2)需走两次,而其他格只能走一次。
能否满足上述要求,且最后停在(r2,c2)上?
3.2 样例分析
如上所述。
解法分析
这道题其实和普通的搜索题有神似,但这道题(r2,c2)需要走两次,那就要处理这个问题。其实,
最一般的做法是暴力广搜,在(r2,c2)上特判一下即可。但我有一个做法:
不难发现,若第一次已经走到了(r2,c2)上的话,只要周围还有一个格子能走,就一定可以成功。
那么,不仿先将周围的一块格子先保护起来,然后再跑一遍广搜,只要走得到(r2,c2),那就可
已第二次走到(r2,c2)。
4 AC代码
ACCode #1
// From realcomplex
// Rating 2401
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int conf[N][N];
void ini(){
for(int i = 0;i<N;i++)
for(int j = 0;j<N;j++)
conf[i][j] = 3;
}
void dfs(int i,int j){
conf[i][j]+=1;
if(conf[i][j]>=3)return;
dfs(i,j+1);
dfs(i+1,j);
dfs(i-1,j);
dfs(i,j-1);
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ini();
int n,m;
cin >> n >> m;
char c;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin >> c;
conf[i][j] = (c=='X')+1;
}
}
int c1,c2,e1,e2;
cin >> c1 >> c2 >> e1 >> e2;
conf[c1][c2] = 1;
dfs(c1,c2);
if(conf[e1][e2]>=3)
puts("YES");
else
puts("NO");
return 0;
}
ACCode #002
// From cnnfls_csy
// Rating 2937
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<queue>
#define sqr(x) (x)*(x)
using namespace std;
int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
int n,m,i,j,ex,ey,sx,sy,x,y;
char mp[505][505];
queue<int> qx,qy;
int main()
{
cin>>n>>m;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
cin>>mp[i][j];
}
}
cin>>sx>>sy>>ex>>ey;
qx.push(sx);
qy.push(sy);
while (!qx.empty())
{
x=qx.front();
y=qy.front();
qx.pop();
qy.pop();
for (i=1;i<=4;i++)
{
if (mp[x+dx[i]][y+dy[i]]=='.')
{
mp[x+dx[i]][y+dy[i]]='X';
qx.push(x+dx[i]);
qy.push(y+dy[i]);
}
else if (mp[x+dx[i]][y+dy[i]]=='X'&&x+dx[i]==ex&&y+dy[i]==ey)
{
cout<<"YES";
return 0;
}
}
}
cout<<"NO";
return 0;
}
ACCode #003
// From Heart_Blue
// Rating 2425
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 5e2 + 10;
char chess[N][N];
int dx[] = { 0,0,1,-1 };
int dy[] = { -1,1,0,0 };
int flag[N][N];
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int n, m;
cin >> n >> m;
MEM(chess, 'X');
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> chess[i][j];
}
}
int sx, sy;
int ex, ey;
cin >> sx >> sy >> ex >> ey;
int cnt = 0;
for (int i = 0; i < 4; i++)
{
int x = ex + dx[i];
int y = ey + dy[i];
if (chess[x][y] == '.') cnt++;
}
if (sx == ex && sy == ey)
{
if (cnt > 0) puts("YES");
else puts("NO");
return 0;
}
if (abs(sx - ex) + abs(sy - ey) == 1)
{
if (chess[ex][ey] == 'X')
{
puts("YES");
}
else
{
if (cnt > 0) puts("YES");
else puts("NO");
}
return 0;
}
MEM(flag, 0);
list<pair<int, int>> lp;
lp.push_back({ sx,sy });
flag[sx][sy] = 1;
while (!lp.empty())
{
int x, y;
tie(x, y) = lp.front();
lp.pop_front();
for (int i = 0; i < 4; i++)
{
int tx = x + dx[i];
int ty = y + dy[i];
if (flag[tx][ty]) continue;
flag[tx][ty] = 1;
if (chess[tx][ty] == 'X') continue;
lp.push_back({ tx,ty });
}
}
if (flag[ex][ey])
{
if (chess[ex][ey] == 'X') puts("YES");
else if (cnt > 1) puts("YES");
else puts("NO");
}
else puts("NO");
return 0;
}