题目链接
http://codeforces.com/contest/197/problem/D
题目大意
给你一张图,图可以无限拼接(不能旋转)
问你一个人能不能从S位置走到无穷远的地方
思路
- 跑四张图,记录是否有一个点跑了两次就行了
- 用绝对座标,vis用来记录当前点是在哪张图,同样的记录是否有一个点跑了两次就行了
代码
1.
#include<bits/stdc++.h>
using namespace std;
int r, c;
char s[2000][2000];
struct P
{
int x, y;
};
queue<P>q;
P qq;
bool vis[3005][3005];
int cnt[1505][1505];
int dx[5]={1, 0, -1, 0};
int dy[5]={0, 1, 0, -1};
void bfs()
{
while(!q.empty())
{
P np = q.front();
q.pop();
//cout<<np.x<<' '<<np.y<<endl;
for(int i=0; i<4; ++i)
{
P xp;
xp.x = np.x + dx[i];
xp.y = np.y + dy[i];
if(xp.x < 0)xp.x+=2*r;
if(xp.y < 0)xp.y+=2*c;
if(xp.x >= 2*r)xp.x -= 2*r;
if(xp.y >= 2*c)xp.y -= 2*c;
if(xp.x >= 0 && xp.y >= 0 && xp.x < 2*r && xp.y < 2*c && !vis[xp.x][xp.y] && s[xp.x%r][xp.y%c] != '#')
{
q.push(xp);
vis[xp.x][xp.y]=1;
++cnt[xp.x%r][xp.y%c];
if(cnt[xp.x%r][xp.y%c] >= 2)
{
puts("Yes");
return ;
}
}
}
}
puts("No");
}
int main()
{
memset(cnt, 0, sizeof(cnt));
memset(vis, 0, sizeof(vis));
while(!q.empty())q.pop();
scanf("%d%d", &r, &c);
for(int i=0; i<r; ++i)
scanf("%s", s[i]);
for(int i=0; i<r; ++i)
{
for(int j=0; j<c; ++j)
{
if(s[i][j]=='S')
{
qq.x = i;
qq.y = j;
q.push(qq);
vis[i][j]=1;
break;
}
}
}
bfs();
return 0;
}
2.
//将来补上orz
反思
首先这题打重现的时候其实是想到了的,但是实现上又出了问题,
我的四张图跑到边界的时候并不能到另一张图,于是我陷入了无限开图的死循环中。。。orz
其实当时如果再仔细想下如何解决需要无限开图的方法的话,或许能想到绝对座标这么个东西(其实是根本没想到跑到边界再出现到另一张图的操作orz)