題目鏈接
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)