http://codeforces.com/contest/510/problem/B
给你一张地图,判断是否存在一个圈
我的劣质代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
char mp[55][55];
int vis[55][55];
int dirx[]={0,0,1,-1};
int diry[]={1,-1,0,0};
bool flag;
int sx,sy;
char colc;
struct node{
int x,y;
}p[55][55];
void print_ans(int x,int y){
if(p[x][y].x==x&&p[x][y].y==y) return ;
print_ans(p[x][y].x,p[x][y].y);
printf("%d%d -->",x,y);
}
bool check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&mp[x][y]==colc) return true;
return false;
}
bool dfs(int x,int y,int cnt){
if(flag) return true;
for(int i=0;!flag&&i<4;++i){
int vx=x+dirx[i];
int vy=y+diry[i];
if(vx==sx&&vy==sy&&cnt>=4) {flag=true;return true;}
if(!check(vx,vy)) continue;
if(!vis[vx][vy]){
vis[vx][vy]=1;
if(dfs(vx,vy,cnt+1)) return true;
if(dfs(x,y,cnt)) return true;
}
}
return false;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
cin>>n>>m;
for(int i=0;i<n;++i) scanf("%s",mp[i]);
flag=false;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
memset(vis,0,sizeof(vis));
sx=i,sy=j;
colc=mp[i][j];
p[i][j].x=i;
p[i][j].y=j;
vis[i][j]=1;
if(dfs(i,j,1)){printf("Yes\n");return 0;}
}
}
printf("No\n");
return 0;
}
除非往回走,否则只有走了一个圈,才有可能走到以前走过的点,因为只有4个方向可以走
#include<bits/stdc++.h>
using namespace std;
int n,m;
char pic[55][55];
int vis[55][55];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
bool dfs(int x,int y,int px,int py,char c){
vis[x][y]=1;
for(int i=0;i<4;++i){
int tx=x+dx[i];
int ty=y+dy[i];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&(pic[tx][ty]==c)&&(tx!=px||ty!=py)){
if(vis[tx][ty]) return true;
if(dfs(tx,ty,x,y,c)) return true;
}
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;++i) scanf("%s",pic[i]);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(!vis[i][j])
if(dfs(i,j,-1,-1,pic[i][j])){
printf("Yes\n");
return 0;
}
}
}
printf("No\n");
return 0;
}
两个方向的并查集
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, m;
#define FOR(x, y, z) for(int x = y; x <= z; x ++)
#define p(i, j) (i - 1) * m + j
char a[60][60];
int fa[3600];
int yy = 0;
int find(int x){
if(x == fa[x]) return x;
int k = find(fa[x]);
fa[x] = k;
return k;
}
void insert(int i, int j){
int x = find(i), y = find(j);
if(x == y) {
yy = 1;
return;
}
fa[x] = y;
}
int main(){
scanf("%d %d", &n, &m);
char ch;
scanf("%c", &ch);
FOR(i, 1, n){
FOR(j, 1, m){
scanf("%c", &a[i][j]);
}
scanf("%c", &ch);
}
FOR(i, 1, n)
FOR(j, 1, m)
fa[p(i, j)] = p(i, j);
FOR(i, 1, n)
FOR(j, 1, m){
if(j < m && a[i][j] == a[i][j + 1]) insert(p(i, j), p(i, j + 1));
if(i < n && a[i][j] == a[i + 1][j]) insert(p(i, j), p(i + 1, j));
}
if(yy == 1) printf("Yes\n");
else printf("No\n");
return 0;
}