dfs+bfs專題(簡單題)
阿新 • • 發佈:2019-01-05
bfs + 輸出路徑
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; int maze[5][5]; int way[4][2] = {0,1,1,0,-1,0,0,-1}; struct node { int x,y,s,pre; node(int a,int b,int c,int d) {x = a; y = b; s = c; pre = d;} node(){} }ans[110]; int sta[105]; void bfs() { queue<node> q; q.push(node(0,0,0,-1)); int num = 0; while(!q.empty()) { node temp = q.front(); q.pop(); ans[num++] = temp; int x = temp.x,y = temp.y; if(x == 4 && y == 4) break; for(int i = 0; i < 4; i++) { int newx = x + way[i][0] , newy = y + way[i][1]; if(maze[newx][newy] || newx < 0 || newx > 4 || newy < 0 || newy > 4) continue; maze[newx][newy] = 1; node no = node(newx,newy,temp.s+1,num-1); q.push(no); } } int th = num - 1, snum = 0; while(ans[th].pre != -1) { sta[++snum] = ans[th].pre; th = ans[th].pre; } while(snum != 0) { printf("(%d, %d)\n",ans[sta[snum]].x,ans[sta[snum]].y); snum--; } printf("(4, 4)\n"); } int main() { for(int i = 0; i < 5; i++) for(int j = 0; j < 5; j++) scanf("%d",&maze[i][j]); bfs(); return 0; }
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; int col[10]; int maze[10][10]; int n,m; char s[15]; int ans = 0; void dfs(int nowr,int num) { if(num == m) { ans++ ; return;} if(nowr >= n) return; for(int i = 0; i < n; i++) { if(maze[nowr][i] || col[i]) continue; col[i] = 1; dfs(nowr+1,num+1); col[i] = 0; } dfs(nowr + 1, num); } int main() { while(~scanf("%d%d",&n,&m)) { if(n == -1 && m == -1) break; for(int i = 0; i < n; i++) { scanf("%s",s); for(int j = 0; j < n ; j++) maze[i][j] = s[j] == '#'?0:1; } ans = 0; dfs(0,0); printf("%d\n",ans); } return 0; }
C.三維迷宮問題 POJ 2251
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> using namespace std; const int maxn = 35; struct node { int x,y,z,s; node(int a,int b,int c,int d){x = a; y = b; z = c; s = d;} }; int maze[maxn][maxn][maxn]; int way[6][3] = {0,0,1,0,0,-1,0,1,0,0,-1,0,1,0,0,-1,0,0}; int st[3],p[3]; char s[100]; int m,n,Q; void bfs() { queue<node > q; q.push(node(st[0],st[1],st[2],0)); int flag = 0; maze[st[0]][st[1]][st[2]] = 1; while(!q.empty()) { node temp = q.front(); q.pop(); int x = temp.x, y = temp.y, z = temp.z, s = temp.s; if(x == p[0] && y == p[1] && z == p[2]) { flag = 1; printf("Escaped in %d minute(s).\n",s); break; } for(int i = 0; i < 6; i++) { int nx = x + way[i][0], ny = y + way[i][1] , nz = z + way[i][2]; if(maze[nx][ny][nz] || nx < 0 || nx >= m || ny < 0 || ny >= n || nz < 0 || nz >= Q) continue; maze[nx][ny][nz] = 1; q.push(node(nx,ny,nz,s+1)); } } if(!flag) printf("Trapped!\n"); } int main() { while(~scanf("%d%d%d",&m,&n,&Q) && n+m+Q) { for(int i = 0; i < m; i++) for(int j = 0; j < n; j++) { scanf("%s",s); for(int k = 0; k < Q;k ++) { maze[i][j][k] = 0; if(s[k] == 'S') st[0] = i,st[1] = j,st[2] = k; else if(s[k] == 'E') p[0] = i,p[1] = j,p[2] = k; else if(s[k] == '#') maze[i][j][k] = 1; } } bfs(); } return 0; }
D.一個追牛的人的問題,記得空間別開小,會gg POJ 3278
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e5 + 10;
int n,k;
struct node
{
int v,s;
node(int a,int b){v = a; s = b;}
};
int vis[maxn*2];
int bfs()
{
queue<node> q;
q.push(node(n,0));
for(int i = 0; i < maxn; i++) vis[i] = 0;
vis[n] = 1;
while(!q.empty())
{
node temp = q.front(); q.pop();
if(temp.v == k)
{
printf("%d\n",temp.s);
break;
}
int nx = temp.v + 1,ns = temp.s + 1;
if(nx <= k + 1 && !vis[nx]) {vis[nx] = 1;q.push(node(nx,ns));}
nx = temp.v * 2;
if(nx < 2*k && !vis[nx]) {vis[nx] = 1;q.push(node(nx,ns));}
nx = temp.v-1;
if(nx >= 0 && !vis[nx]) {vis[nx] = 1;q.push(node(nx,ns));}
}
}
int main()
{
while(~scanf("%d%d",&n,&k))
bfs();
return 0;
}
E.這個應該叫開關問題 POJ
3279
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int ori[20][20];
int op[20][20];
int moni[20][20];
int way[4][2] = {0,1,0,-1,1,0,-1,0};
int n,m;
bool ans = false;
void filp(int i,int j)
{
moni[i][j] = !moni[i][j];
for(int x = 0; x < 4; x++)
{
int nx = i + way[x][0] , ny = j + way[x][1];
if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
moni[nx][ny] = !moni[nx][ny];
}
}
void conti(int time)
{
for(int i = 1; i < n; i++)
for(int j = 0; j < m; j++)
{
if(moni[i-1][j])
{op[i][j] = 1;filp(i,j);}
}
int flag = 1;
for(int i = 0; i < m; i++)
if(moni[n-1][i]) { flag = 0; break;}
if(flag)
{
ans = true;
for(int i = 0; i < n ; i++)
{
for(int j = 0; j < m ; j++)
j == 0?printf("%d",op[i][j]) : printf(" %d",op[i][j]);
printf("\n");
}
}
}
void solve()
{
ans = false;
for(int i = 0; i < (1 << m); i++) //翻轉第一行的全部情況
{
if(ans) break;
memset(op,0,sizeof(op));
memcpy(moni,ori,sizeof(ori));
int x = 0;
for(int j = 1; j <= i; j = (1<<x))
{
if((j&i) == j) {op[0][x] = 1, filp(0,x);}
x++;
}
conti(i);
}
if(ans == false) printf("IMPOSSIBLE\n");
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i = 0; i < n ; i++)
for(int j = 0; j < m ; j++)
scanf("%d",&ori[i][j]);
solve();
}
return 0;
}
F.一個非要素數的問題 POJ
3126
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
int a,b;
struct node
{
int to,s;
int val[4];
node(){}
node(int a,int b)
{
to = a; s = b;
val[0] = to/1000, val[1] = to/100%10,
val[2] = to/10%10, val[3] = to%10;
}
};
int prime[10000];
int vis[10000];
bool isPrime(int n)
{
// cout << n <<endl;
int temp = (int)sqrt(n*1.0);
for(int i = 2; i <= temp ; i++)
if(n%i == 0) return 0;
return 1;
}
void pre()
{
for(int i = 1000; i < 10000; i++)
if(isPrime(i)) prime[i] = 1;
}
int bfs()
{
memset(vis,0,sizeof(vis));
queue<node> q;
q.push(node(a,0));
vis[a] = 1;
while(!q.empty())
{
node temp = q.front(); q.pop();
int to = temp.to, s = temp.s;
if(to == b) {printf("%d\n",s); break;}
int nval[4];
for(int i = 0; i < 4; i++) nval[i] = temp.val[i];
for(int i = 0; i < 4; i++)
for(int j = 0; j < 10; j++)
{
int newval = 0;
for(int k = 0; k < 4; k++)
if(k != i) newval = (newval * 10) + nval[k];
else newval = (newval*10) + j;
if(!vis[newval] && prime[newval])
vis[newval] = 1, q.push(node(newval,s+1));
}
}
}
int main()
{
pre();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&a,&b);
bfs();
}
return 0;
}
G.HDU 1010
一個我已經寫過還是超時的問題
記得需要奇偶剪枝。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 10;
int maze[maxn][maxn];
bool vis[maxn][maxn];
int way[4][2] = {1,0,-1,0,0,-1,0,1};
int s[2],p[2];
int n,m,t;
bool ans = false;
int dis(int x,int y)
{
int thdis = abs(x-p[0]) + abs(y-p[1]);
return thdis;
}
int dfs(int x,int y,int step)
{
if(x == p[0] && y == p[1] && step == t){ans = true; return 1;}
if(ans) return 1;
if(step + dis(x,y) > t) return 0;
for(int i = 0; i < 4; i++)
{
int newx = x + way[i][0] , newy = y + way[i][1];
if(!vis[newx][newy] && newx >= 0 && newx < n &&
newy >= 0 && newy < m && maze[newx][newy] == 0
&& step + 1 <= t)
{
int mdis = dis(newx,newy);
if(((t - (step+1) - mdis)%2)) return 0;
vis[newx][newy] = 1;
if(dfs(newx,newy,step+1)) return 1;
vis[newx][newy] = 0;
}
}
return 0;
}
char str[1000];
int main()
{
while(~scanf("%d%d%d",&n,&m,&t) && n+m+t)
{
ans = 0;
memset(vis,0,sizeof(vis));
for(int i = 0 ; i < n ; i++)
{
scanf("%s",str);
for(int j = 0 ; j < m ; j++)
{
maze[i][j] = 0;
if(str[j] == 'S') s[0] = i, s[1] = j;
else if(str[j] == 'D') p[0] = i, p[1] = j;
else if(str[j] == 'X') maze[i][j] = 1;
}
}
vis[s[0]][s[1]] = 1;
dfs(s[0],s[1],0);
vis[s[0]][s[1]] = 0;
int sdis = dis(s[0],s[1]);
if((t - sdis) % 2 != 0 || t < sdis) {printf("NO\n"); continue;}
ans == 1 ? printf("YES\n") : printf("NO\n");
}
return 0;
}
H.比油田更簡單的flood fill HDU 1312
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int maze[30][30];
char str[1000];
int st[2];
int way[4][2] = {0,1,0,-1,-1,0,1,0};
int ans = 0,n,m;
void dfs(int x,int y)
{
ans ++;
for(int i = 0; i < 4; i++)
{
int nx = x + way[i][0], ny = y + way[i][1];
if(!maze[nx][ny] && nx >= 0 && ny >= 0
&& nx < n && ny < m)
{
maze[nx][ny] = 1;
dfs(nx,ny);
}
}
}
int main()
{
while(~scanf("%d%d",&m,&n) && n+m)
{
ans = 0;
for(int i = 0; i < n; i++)
{
scanf("%s",str);
for(int j = 0; j < m; j++)
{
maze[i][j] = 0;
if(str[j] == '#') maze[i][j] = 1;
if(str[j] == '@') st[0] = i,st[1] = j;
}
}
maze[st[0]][st[1]] = 1;
dfs(st[0],st[1]);
printf("%d\n",ans);
}
return 0;
}
I.油田問題
比上面那個稍稍難一點的flood fill HDU 1241
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int maze[150][150];
char str[1000];
int st[2];
int way[8][2] = {0,1,0,-1,-1,0,1,0,1,1,1,-1,-1,1,-1,-1};
int ans,n,m;
void dfs(int x,int y)
{
for(int i = 0; i < 8; i++)
{
int nx = x + way[i][0], ny = y + way[i][1];
if(!maze[nx][ny] && nx >= 0 && ny >= 0
&& nx < n && ny < m)
{
maze[nx][ny] = 1;
dfs(nx,ny);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m) && n+m)
{
ans = 0;
for(int i = 0; i < n; i++)
{
scanf("%s",str);
for(int j = 0; j < m; j++)
{
maze[i][j] = 0;
if(str[j] == '*') maze[i][j] = 1;
}
}
for(int i = 0; i < n ; i++)
for(int j = 0; j < m ; j++)
{
if(maze[i][j] == 0)
{
ans ++;
maze[i][j] = 1;
dfs(i,j);
}
}
printf("%d\n",ans);
}
return 0;
}
J.論如何逃出火災現場問題 UVA 11624
什麼,一個bfs不行?那就兩個好了
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1050;
const int inf = 0x3f3f3f3f;
char str[maxn];
int Time[maxn][maxn];
int maze[maxn][maxn];
int vis[maxn][maxn];
int f[maxn][2],J[2];
int way[4][2] = {1,0,-1,0,0,1,0,-1};
int fnum = 0,n,m;
struct node
{
int x,y,t;
node(int a,int b,int c){x = a ; y = b ; t = c ;}
};
void bfspre()
{
memset(vis,0,sizeof(vis));
memset(Time,inf,sizeof(Time));
queue<node> q;
for(int i = 0; i < fnum; i++)
{
vis[ f[i][0] ][f [i][1] ] = Time[f[i][0]][f[i][1]] = 1;
q.push(node(f[i][0],f[i][1],0));
}
while(!q.empty())
{
node temp = q.front(); q.pop();
int x = temp.x, y = temp.y, t = temp.t;
Time[x][y] = t;
for(int i = 0; i < 4; i++)
{
int nx = x + way[i][0] , ny = y + way[i][1];
if(nx < 0 || nx >= n || ny < 0 || ny >= m || maze[nx][ny]) continue;
if(!vis[nx][ny])
{
vis[nx][ny] = 1;
q.push(node(nx,ny,t+1));
}
}
}
}
void bfs()
{
queue<node>q;
q.push(node(J[0],J[1],0));
maze[J[0]][J[1]] = 1;
int mark = 0;
while(!q.empty())
{
node temp = q.front(); q.pop();
int x = temp.x, y = temp.y, t = temp.t;
for(int i = 0; i < 4; i++)
{
int nx = x + way[i][0] , ny = y + way[i][1];
if(nx < 0 || ny < 0 || nx >= n || ny >= m)
{
printf("%d\n",t + 1);
mark = 1;
break;
}
if(maze[nx][ny]) continue;
if(!maze[nx][ny] && t + 1 < Time[nx][ny])
{
maze[nx][ny] = 1;
q.push(node(nx , ny , t+1));
}
}
if(mark) break;
}
if(!mark) printf("IMPOSSIBLE\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
fnum = 0;
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
{
scanf("%s",str);
for(int j = 0; j < n; j++)
{
maze[i][j] = 0;
if(str[j] == '#') maze[i][j] = 1;
if(str[j] == 'F') f[fnum][0] = i, f[fnum++][1] = j;
if(str[j] == 'J') J[0] = i, J[1] = j;
}
}
bfspre();
bfs();
}
return 0;
}
K.閒著無聊倒水玩兒問題 POJ 3414
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
struct node
{
int i,j,s,way,pre;
node(){}
node(int a,int b,int c,int d){i = a; j = b; s = c;pre = d;}
}pro[1005];
bool vis[105][105];
int anum = 1;
int a,b,c;
char out[10][20] = {" ","FILL(1)", "FILL(2)", "DROP(1)" , "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
void print(int id)
{
if(pro[id].pre != 1)
print(pro[id].pre);
printf("%s\n",out[pro[id].way]);
}
void bfs()
{
int mark = 0;
anum = 1;
memset(vis,0,sizeof(vis));
queue<node > q;
q.push(node(0,0,0,0));
while(!q.empty())
{
node temp = q.front(); q.pop();
pro[anum++] = temp;
int x = temp.i, y = temp.j, s = temp.s;
//cout << x <<" " << y << endl;
if(x == c || y == c)
{
printf("%d\n",s);
print(anum-1);
mark = 1;
break;
}
node change = node(a,y,s+1,anum-1);
if(!vis[a][y])
change.way = 1, vis[a][y] = 1,q.push(change);
change.i = x, change.j = b;
if(!vis[x][b])
change.way = 2,vis[x][b] = 1,q.push(change);
change.i = 0, change.j = y;
if(!vis[0][y])
change.way = 3,vis[0][y] = 1,q.push(change);
if(!vis[x][0])
change.way = 4, vis[x][0] = 1,change.i = x, change.j = 0,q.push(change);
if(y+x > b)
{
change.i = y+x-b, change.j = b;
if(!vis[y+x-b][b])
vis[y+x-b][b] = 1, change.way = 5, q.push(change);
}
else
{
change.i = 0, change.j = y+x;
if(!vis[0][y+x])
vis[0][y+x] = 1, change.way = 5, q.push(change);
}
if(x+y > a)
{
change.i = a, change.j = x+y-a;
if(!vis[a][x+y-a])
vis[a][x+y-a] = 1, change.way = 6, q.push(change);
}
else
{
change.i = x+y, change.j = 0;
if(!vis[x+y][0])
vis[x+y][0] = 1,change.way = 6,q.push(change);
}
}
if(!mark) printf("impossible\n");
}
int main()
{
while(~scanf("%d%d%d",&a,&b,&c))
{
bfs();
}
return 0;
}
L.並不是bfs + dfs 只是模擬題 POJ 3087
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char s1[150],s2[150];
char temp1[150], temp2[150];
char sta[300],tar[300];
int main()
{
int t,n;
scanf("%d",&t);
for(int kase = 1; kase <= t; kase ++)
{
scanf("%d",&n);
scanf("%s%s%s",s1,s2,tar);
int num = 0;
while(num < 10000)
{
for(int i = 0; i < 2*n; i++) sta[i] = i%2?s1[i/2] : s2[i/2];
sta[2*n] = '\0';
num++;
if(strcmp(sta,tar) == 0) break;
for(int i = 0; i < n; i++)
s1[i] = sta[i]; s1[n] = '\0';
for(int i = n; i <= 2*n; i++)
s2[i-n] = sta[i]; s2[2*n] = '\0';
// cout << sta << " " << s1 << " " << s2 << endl;
}
printf("%d ",kase);
if(num == 10000) printf("-1\n");
else printf("%d\n",num);
}
return 0;
}