您的位置:首页 > 其它

BFS DFS 搜索专题合集

2016-04-27 21:35 417 查看
在准备蓝桥杯,最重要的当然是搜索啦啦,开个搜索专题专门贴题,不定时更新。

hdu 2181 哈密顿绕行世界问题

因为数据不大,所以简单的深搜就可以了,注意从小到大排下序,防止数据随机给。

#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
using namespace std;
vector<int> v[21];
int book[21];
int ttime;
int temp[23];
int m;
void dfs(int s,int t);
int main(){
for(int i=1;i<=20;i++){
for(int j=0;j<3;j++){
int x;
scanf("%d",&x);
v[i].push_back(x);
}
//这里应该排序
}
scanf("%d",&m);
while(m){
ttime = 0;
memset(book,0,sizeof(book));
temp[0] = m;
book[m] = 1;
dfs(m,0);
scanf("%d",&m);
}
return 0;
}

void dfs(int s,int t){
if(t==19){
int status = 0;
for(int i=0;i<v[s].size();i++){
if(v[s][i]==m){//注意是环
status = 1;
temp[t+1] = m;
break;
}
}
if(status){
printf("%d:  ",++ttime);
for(int i=0;i<=t+1;i++){
printf("%d",temp[i]);
if(i!=t+1)	printf(" ");
else printf("\n");
}
}
return ;
}
for(int i=0;i<v[s].size();i++){
if(book[v[s][i]]==0){
book[v[s][i]] = 1;
temp[t+1] = v[s][i];
dfs(v[s][i],t+1);
book[v[s][i]] = 0;
}
}
}
nyoj 1336 火车进栈

这题是卡特兰数,但是因为数据量小的原因,就用dfs做了。

每深搜一个排列,则模拟进栈,看是否符合。algorithm头文件里有bool next_permutation( iterator start, iterator end ); 全排列函数,会对该排列进行下一个排列,若不存在下一个排列,则返回false。这样其实就不用深搜了。

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<vector>
using namespace std;
int book[23];
int temp[23];
int N;
int time;
int check();
void dfs(int t);
int main(){
while(scanf("%d",&N)!=EOF){
memset(book,0,sizeof(book));
time = 0;
dfs(0);

}
return 0;
}
//模拟进栈
int check(){
stack<int>s;
vector<int >v;
int t = 0;
for(int i=1;i<=N;i++){
while(!s.empty()&&s.top()==temp[t]){
v.push_back(s.top());
s.pop();
t++;
}
if(i==temp[t]){
v.push_back(i);
t++;
}
else{
s.push(i);
}
while(!s.empty()&&s.top()==temp[t]){
v.push_back(s.top());
s.pop();
t++;
}

}
for(int i=0;i<N;i++){
if(v[i]!=temp[i])	return 0;
}
return 1;
}
//搜出全排列
void dfs(int t){
if(t==N){
int status = check();
if(status&&time<20){
time++;
for(int i=0;i<N;i++){
printf("%d",temp[i]);
}
printf("\n");
}
return ;
}
for(int i=1;i<=N;i++){
if(book[i]==0){
temp[t] = i;
book[i] = 1;
dfs(t+1);
if(time>=20)	return ;
book[i] = 0;
}
}
}



方老师与素数 851 (Prime Path poj 3126 题目一样)

我用了最朴素最朴素的bfs,跑了500ms+……
搜出当前剩下的素数与该节点有一个数不同,搜到终点结束就可以了,贴一份我自己的和大神的代码。。。

弱弱我的

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
#include<queue>
using namespace std;
vector<int>p;
int step;
struct node{
int x;
int s;
};
int bfs(int s,int e);
void init();
int main(){
init();
int n,m;
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
step = 0;
int s = bfs(n,m);
if(s){
printf("%d\n",step);
}
else{
printf("Impossible\n");
}
}
return 0;
}

int bfs(int s,int e){
queue<node>q;
vector<int>v(p.size(),0);
node n;
n.x = s;
n.s = 0;
q.push(n);
for(int i=0;i<p.size();i++){
if(n.x==p[i]){
v[i] = 1;
}
}
while(!q.empty()){
node temp = q.front();
q.pop();
if(temp.x==e){
step = temp.s;
return 1;
}
for(int i=0;i<p.size();i++){
if(v[i]==0){
if(temp.x/1000!=p[i]/1000&&temp.x%1000==p[i]%1000){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/1000==p[i]/1000&&(temp.x%1000)/100!=(p[i]%1000)/100&&temp.x%100==p[i]%100){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/100==p[i]/100&&(temp.x%100)/10!=(p[i]%100)/10&&temp.x%10==p[i]%10){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/10==p[i]/10&&temp.x%10!=p[i]%10){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
}
}
}
return 0;
}

void init(){
int temp[5000];
int nt = 0;
temp[nt++] = 2;
for(int i=3;i<=10000;i+=2){
int j=0;
for(;j<nt;j++){
if(i%temp[j]==0)
break;
}
if(j==nt){
temp[nt++]=i;
if(i>=1000)
p.push_back(i);
}
}
}


重新写了一次

#include<stdio.h>
#include<iostream>
#include<queue>
#include<vector>
#include<string.h>
using namespace std;
vector<int>v;
int x,y;
int status,step;
struct node{
int x;
int s;
};
void dfs();
void init();
int book[10000];
int main(){
init();
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&x,&y);
status = 0;
memset(book,0,sizeof(book));
dfs();
if(status){
printf("%d\n",step);
}
else{
printf("Impossible\n");
}
}
return 0;
}

void dfs(){
node c;
c.x = x;
c.s = 0;
queue<node>q;
q.push(c);
book[x] = 1;
while(!q.empty()){
node temp = q.front();
q.pop();
if(temp.x==y){
status = 1;
step = temp.s;
return ;
}
for(int i=0;i<v.size();i++){
if(book[v[i]]==0){
node p;
p.x = v[i];
p.s = temp.s + 1;
if(temp.x/1000!=v[i]/1000&&temp.x%1000==v[i]%1000){
q.push(p);
book[v[i]]=1;
}
else if(temp.x/1000==v[i]/1000&&(temp.x%1000)/100!=(v[i]%1000)/100&&temp.x%100==v[i]%100){
q.push(p);
book[v[i]]=1;
}
else if(temp.x/100==v[i]/100&&(temp.x%100)/10!=(v[i]%100)/10&&temp.x%10==v[i]%10){
q.push(p);
book[v[i]]=1;
}
else if(temp.x/10==v[i]/10&&temp.x%10!=v[i]%10){
q.push(p);
book[v[i]]=1;
}
}
}
}

}

void init(){
int t[8000];
int n = 0;
t[n++] = 2;
for(int i=3;i<=10000;i+=2){
int j=0;
for(;j<n;j++){
if(i%t[j]==0)	break;
}
if(j==n){
t[n++] = i;
if(i>=1000)
v.push_back(i);
}
}

}


大神的

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <queue>

using namespace std;

int num[2005], m, n;
int isPrime[10005], vis[10005];

typedef struct HeHe{
int shu;
int step;
}Node;

queue<Node> que;

int IsPrime(int x){
int i;
for(i = 2; i <= x / 2; i++){
if(x % i == 0) return 0;
}
return 1;
}

void bfs(){
Node q;
q.shu = n;
q.step = 0;
que.push(q);
vis[q.shu] = 1;
while(!que.empty()){
q = que.front();
que.pop();
if(q.shu == m){
printf("%d\n", q.step);
return;
}
Node now;
now.step = q.step + 1;
int i;
for(i = q.shu + 1000; i < 10000; i+= 1000){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu - 1000; i >= 1000; i -= 1000){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu + 100; i < (q.shu - (q.shu % 1000) + 1000); i += 100){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu - 100; i >= (q.shu - (q.shu % 1000)); i -= 100){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu + 10; i < (q.shu - (q.shu % 100) + 100); i += 10){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu - 10; i >= (q.shu - (q.shu % 100)); i -= 10){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu + 1; i < (q.shu - (q.shu % 10) + 10); i++){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
for(i = q.shu - 1; i >= (q.shu - (q.shu % 10)); i--){
if(isPrime[i] && !vis[i]){
now.shu = i;
vis[i] = 1;
que.push(now);
}
}
}
}

int main(){
int i, j = 0;
for(i = 1000; i <= 9999; i++){
if(IsPrime(i)){
num[j++] = i;
}
}
memset(isPrime, 0, sizeof(isPrime));
for(i = 0; i < j; i++) isPrime[num[i]] = 1;
int T;
scanf("%d", &T);
while(T--){
memset(vis, 0, sizeof(vis));
while(!que.empty()) que.pop();
scanf("%d%d", &n, &m);
bfs();
}
return 0;
}


棋盘问题 (poj 1321)

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
char a[9][9];
int book[9];
int n,k;
int step;
void dfs(int p,int t);
int main(){

scanf("%d%d",&n,&k);
while(n!=-1&&k!=-1){
for(int i=0;i<n;i++){
scanf("%s",a[i]);
}
step = 0;
memset(book,0,sizeof(book));
dfs(0,0);
printf("%d\n",step);
scanf("%d%d",&n,&k);
}
return 0;
}

void dfs(int p,int t){
if(t==k){
step++;
return ;
}
if(p==n)	return ;
for(int i=0;i<n;i++){
if(a[p][i]=='#'&&book[i]==0){
book[i] = 1;
dfs(p+1,t+1);
book[i] = 0;
}
}
dfs(p+1,t);
}


数独(nyoj 722)

dfs 用一个行标记,列标记,块标记就行了

#include<stdio.h>
#include<iostream>
#include<queue>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10][10];
int hang[10][10];
int lie[10][10];
int kuai[10][10];
int status;
void solve(int x,int y);
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(hang,0,sizeof(hang));
memset(lie,0,sizeof(lie));
memset(kuai,0,sizeof(kuai));
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
scanf("%d",&a[i][j]);
if(a[i][j]){
hang[i][a[i][j]] = 1;
lie[a[i][j]][j] = 1;
kuai[i/3*3 + j/3 + 1][a[i][j]] = 1;
}
}
}
status = 0;
solve(0,0);
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
printf("%d",a[i][j]);
if(j!=8)	printf(" ");
else printf("\n");
}
}
}
return 0;
}
void solve(int x,int y){
if(x==9){
status = 1;
return ;
}
int nx = x,ny = y+1;
if(ny==9){
ny = 0;
nx++;
}
if(a[x][y])	solve(nx,ny);
else
for(int i=1;i<=9;i++){
if(hang[x][i]==0&&lie[i][y]==0&&kuai[x/3*3+y/3+1][i]==0){
hang[x][i]=1;
lie[i][y]=1;
kuai[x/3*3+y/3+1][i]=1;
a[x][y] = i;
solve(nx,ny);
if(status)	return ;
a[x][y] = 0;
hang[x][i]=0;
lie[i][y]=0;
kuai[x/3*3+y/3+1][i]=0;
}
}
}


连接的管道(hdu 5253)

是个伪图论,求最小生成树,标记好点就行了,我用了prim,其他的也可以

#include<stdio.h>
#include<iostream>
#include<queue>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 1010
int a[MAX][MAX];
int book[MAX][MAX];
int n,m;
int d[4][2] = {1,0,0,1,-1,0,0,-1};
struct node{
int x;
int y;
int h;
bool operator < (const node& x )const{
return h>x.h;
}

};
int result;
void solve();
int main(){
int t;
int T = 1;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[i][j]);
}
}
memset(book,0,sizeof(book));
result = 0;
solve();
printf("Case #%d:\n%d\n",T++,result);
}
return 0;
}

void solve(){
priority_queue<node>q;
node c;
c.x = 0;
c.y = 0;
c.h = 0;
q.push(c);
int s = 0;
while(!q.empty()){
if(s==n*m){
return ;
}
node t = q.top();
q.pop();
while(book[t.x][t.y]!=0){
if(q.empty())	return ;
t = q.top();
q.pop();
}
book[t.x][t.y]=1;
result += t.h;
s++;
if(s==n*m){
return ;
}
for(int i=0;i<4;i++){
node temp;
temp.x = t.x + d[i][0];
temp.y = t.y + d[i][1];
if(temp.x>=0&&temp.x<n&&temp.y>=0&&temp.y<m&&book[temp.x][temp.y]==0){
temp.h = abs(a[temp.x][temp.y] - a[t.x][t.y]);
q.push(temp);
}
}
}
}


三个水杯(poj 21)

经典bfs问题,下面注释写得很清楚,状态不重复的搜索就行了。

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
int c[3];	//保存当前水量
int s;	//step步数
};
node s;	//杯子容量
node n;	//开始水量
node e;	//目标水量
char book[1000000];	//标记减少内存
int bfs();
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(book,0,sizeof(book));
for(int i=0;i<3;i++){
scanf("%d",&s.c[i]);
}
for(int i=0;i<3;i++){
scanf("%d",&e.c[i]);
}
n.c[0] = s.c[0];
n.c[1] = n.c[2] = 0;
n.s = 0;
printf("%d\n",bfs());	//若不可以,会直接返回-1
}
return 0;
}
int check(node t){
for(int i=0;i<3;i++){
if(t.c[i]!=e.c[i])	return 0;
}
return 1;
}
//只有100*100*100种可能
int hash(node t){
return t.c[0]*10000+t.c[1]*100+t.c[2];
}
int bfs(){
queue<node>q;
q.push(n);
book[hash(n)] = 1;
while(!q.empty()){
node t = q.front();
q.pop();
if(check(t))	return t.s;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){	//j倒i
if(i!=j){
int m = s.c[i] - t.c[i];	//i的剩余空间
if(t.c[j]<=m)	m = t.c[j];	//若小于等于,则j中有多少水就倒多少水
node temp = t;
temp.c[j] -= m;
temp.c[i] += m;
if(!book[hash(temp)]){
book[hash(temp)] = 1;
temp.s = t.s + 1;
q.push(temp);
}
}
}
}
}
return -1;
}


War Chess (hdu 3345)

优先队列 + bfs,价值最大的那一条路线标记该点即可,注意题意:与敌军相邻则战斗值为零。跨过友军战斗值减一。

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,k;
int sx,sy;
char a[110][110];
char book[110][110];
struct node{
int x,y,v;
bool operator <(const node& x)const{
return v<x.v;
}
};
int d[4][2] = {1,0,0,1,-1,0,0,-1};
void bfs();
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++){
scanf("%s",a[i]);
for(int j=0;j<m;j++){
if(a[i][j]=='Y'){
sx = i;
sy = j;
}
}
}
memset(book,0,sizeof(book));
bfs();
for(int i=0;i<n;i++){
printf("%s\n",a[i]);
}
printf("\n");
}
return 0;
}

void check(node& temp){
for(int i=0;i<4;i++){
node t = temp;
t.x += d[i][0];
t.y += d[i][1];
if(t.x>=0&&t.x<n&&t.y>=0&&t.y<m&&a[t.x][t.y]=='E'){
temp.v = 0;
return ;
}
}
}

void bfs(){
node c;
c.x = sx;
c.y = sy;
c.v = k;
book[c.x][c.y] = 1;
priority_queue<node>q;
q.push(c);
while(!q.empty()){
node temp = q.top();
q.pop();
for(int i=0;i<4;i++){
node t = temp;
t.x += d[i][0];
t.y += d[i][1];
if(t.x>=0&&t.x<n&&t.y>=0&&t.y<m&&!book[t.x][t.y]&&a[t.x][t.y]!='#'&&a[t.x][t.y]!='E'){
if(a[t.x][t.y]=='.')	t.v--;
else if(a[t.x][t.y]=='T') t.v-=2;
else if(a[t.x][t.y]=='R') t.v-=3;
else if(a[t.x][t.y]=='P') t.v--;
if(t.v<0)	continue;
check(t);
q.push(t);
book[t.x][t.y] = 1;
if(a[t.x][t.y]!='P')	a[t.x][t.y] = '*';
}
}
}

}


超级密码 (hdu 1226)BFS

这道题要解决的问题:
1、c进制
2、500位的上限

进制的问题在最后输出时考虑就行了,这道题没有设置若c=2,给你A,B这样的情况,所以大胆写就行
500位上限要用到一点数学

同余的定义:如果m|(a-b)则a同余b即a与b对m取余后的余数相同

定理:

【1】如果a1同余b1(mod m) a2同余b2(mod m)则a1*a2同余b1*b2(mod m)

【2】如果a1同余b1(mod m) a2同余b2(mod m)则a1+a2同余b1+b2(mod m)

证明:

1)a1=b1+k1*m a2=b2+k2*m

a1*a2=b1*b2+(k1*b2+k2*b1+k1*k2*m)m

所以a1*a2同余b1*b2(mod m)

2)

a1=b1+k1*m a2=b2+k2*m

a1+a2=b1+b2+(k1+k2)m

所以a1+a2同余b1+b2(mod m)

如果a和b同余则成上同一个数后一定还是同余的

证明:假设数乘上一个数x

a同余b(mod m) x同余x(mod m)

运用上述定理得ax同余bx(mod m)

举个例子:

N=11 C=10

10

0 1 2 3 4 5 6 7 8 9 10

123同余2(mod m)当在后面加上一个数后相当于先乘上10 两个数还同余 在加上同一个数后还同余 即余数相同那么就没必要

搜123了

所以我们标记一下余数就可以了,因为余数最多有5000个

引用:http://www.xuebuyuan.com/2225384.html (感谢~)

也就是,我们算出每一个可以被表示出的数,若该数能被n整除,则为结果,否则把他取余c标记起来,之后的数取余再为这个数就不用再进队了。

这里可以用%X输入输出十六进制,%X是字母大写,%x是小写

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int book[5010];
int z[17];
int n,c,m;
struct node{
char s[510];
int len;
};
int bfs();
void output(node t);
int cal(node t);
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&c,&m);
memset(z,0,sizeof(z));
for(int i=0;i<m;i++){
int x;
scanf("%X",&x);	//避免了转换
z[x] = 1;
}
if(n==0){
if(z[0])	printf("0\n");
else printf("give me the bomb please\n");
}
else{
memset(book,0,sizeof(book));
if(bfs()){
printf("give me the bomb please\n");
}
}
}
return 0;
}
//每一位枚举可以用的数。依次枚举
int bfs(){
queue<node>q;
for(int i=1;i<16;i++){	//注意第一位不为0 (0为最高位)
if(z[i]){
node t;
t.len = 0;
t.s[t.len++] =  i;
int num = cal(t);
if(!num){
output(t);
return 0;
}
else{
if(book[num]==0){
book[num] = 1;
q.push(t);
}
}
}
}
while(!q.empty()){
node temp = q.front();
q.pop();
for(int i=0;i<16;i++){	//从小到大保证最小
if(z[i]){
temp.s[temp.len++] = i;
int num = cal(temp);
if(!num){
output(temp);
return 0;
}
else if(book[num]==0&&temp.len<=500){
book[num]=1;
q.push(temp);
}
temp.len--;	//要还原
}
}
}
return 1;
}

void output(node t){
for(int i=0;i<t.len;i++){
printf("%X",t.s[i]);
}
printf("\n");
}

int cal(node t){
int num = 0;
for(int i=0;i<t.len;i++){
num = (num*c+t.s[i])%n;
}
return num;
}


亡命逃窜(nyoj 523)BFS

立体的bfs
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int kj[]={0,0,0,0,1,-1},sx[]={0,0,1,-1,0,0},zy[]={1,-1,0,0,0,0};
int map[60][60][60],ac[60][60][60];
int n,m,w,t;
struct hello
{
int x,y,z,step;
};
void bfs()
{
int a,b,x,y,z,sum,loop=0;
queue<hello>Q;
hello ok1={1,1,1,0};
Q.push(ok1);
ac[1][1][1]=1;
while(!Q.empty())
{
x=Q.front().x;
y=Q.front().y;
z=Q.front().z;
sum=Q.front().step;
Q.pop();
if(x==w&&y==n&&z==m)
{loop=1;break;}
for(a=0;a<6;a++)
{
int i=x+kj[a];
int j=y+sx[a];
int p=z+zy[a];
if(ac[i][j][p]==0&&map[i][j][p]==1)
{
hello ok2={i,j,p,sum+1};
Q.push(ok2);
ac[i][j][p]=1;
}
}

}
if(sum<=t&&loop==1)
printf("%d\n",sum);
else
printf("-1\n");

}
int main()
{
int a,b,c,k,kkk;
scanf("%d",&k);
while(k--)
{
memset(ac,0,sizeof(ac));
memset(map,0,sizeof(map));
scanf("%d %d %d %d",&w,&n,&m,&t);
for(c=1;c<=w;c++)
for(a=1;a<=n;a++)
for(b=1;b<=m;b++)
{
scanf("%d",&kkk);
if(kkk==0)
map[c][a]=1;
else
map[c][a][b]=0;
}
if(map[w]
[m]==0||w+n+m>t)
{printf("-1\n");continue;}
bfs();
}
}


[b][b]Dungeon Master(poj 2251)


[/b]
同样是一个三维bfs

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
using namespace std;
int sl,sn,sm;
int el,en,em;
char a[33][33][33];
char book[33][33][33];
int d[6][3] = {0,1,0,0,0,1,0,-1,0,0,0,-1,1,0,0,-1,0,0};
int status;
struct node{
int l,n,m;
int s;
};
void bfs();
int l,n,m;
int main(){
scanf("%d%d%d",&l,&n,&m);
while(l||n||m){
for(int i=0;i<l;i++){
for(int j=0;j<n;j++){
scanf("%s",a[i][j]);
getchar();
for(int k=0;k<m;k++){
if(a[i][j][k]=='S'){
sl = i;
sn = j;
sm = k;
}
else if(a[i][j][k]=='E'){
el = i;
en = j;
em = k;
}
}
}
}
status = 0;
memset(book,0,sizeof(book));
bfs();
if(status==0)	printf("Trapped!\n");
scanf("%d%d%d",&l,&n,&m);
}
return 0;
}
int check(node z){
if(z.l==el&&z.n==en&&z.m==em)	return 1;
return 0;
}
void b1(node t){
book[t.l][t.n][t.m] = 1;
}
int bcheck(node t){
return book[t.l][t.n][t.m];
}
int border(node t){
if(t.l>=0&&t.l<l&&t.n>=0&&t.n<n&&t.m>=0&&t.m<m)	return 1;
return 0;
}
void bfs(){
node t;
t.l = sl;
t.n = sn;
t.m = sm;
t.s = 0;
queue<node>q;
if(check(t)){
printf("Escaped in %d minute(s).\n",t.s);
status = 1;
return ;
}
b1(t);
q.push(t);
while(!q.empty()){
node t = q.front();
q.pop();
for(int i=0;i<6;i++){
node temp = t;
temp.s++;
temp.l += d[i][0];
temp.n += d[i][1];
temp.m += d[i][2];
if(border(temp)&&(a[temp.l][temp.n][temp.m]=='.'||a[temp.l][temp.n][temp.m]=='E')&&bcheck(temp)==0){
b1(temp);
if(check(temp)){
printf("Escaped in %d minute(s).\n",temp.s);
status = 1;
return ;
}
q.push(temp);
}
}
}
}


Salvation(nyoj 1129)

带方向的深搜,若不碰到墙始终按照约定的方向走,所以会死循环,若到达已经到达的点以同一个方向,那么一定会陷入死循环,答案为no,其他就是普通的深搜,标记数组每个方向一个。要仔细方向和前进点。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
char a[110][110];
int book[4][110][110];
int tn,tm;
int xn,xm;
int ans;
int n,m;
void dfs(int x,int y,int t);
//E:0 W:1 S:2 N:3
//d[i][x][y]:i是方向
int d[4][4][2] = {{-1,0,0,1,1,0,0,-1},{1,0,0,-1,-1,0,0,1},{0,1,1,0,0,-1,-1,0},{0,-1,-1,0,0,1,1,0}};
//fun[t][i]:t为方向,i为对应d的下一个方向
int fun[4][4] = {3,0,2,1,2,1,3,0,0,2,1,3,1,3,0,2};
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<n;i++){
scanf("%s",a[i]);
for(int j=0;j<m;j++){
if(a[i][j]=='T'){
tn = i;
tm = j;
}
if(a[i][j]=='X'){
xn = i;
xm = j;
}
}
}
char c[2];
int t;
scanf("%s",c);
if(c[0]=='E')	t = 0;
else if(c[0]=='W')	t = 1;
else if(c[0]=='S')	t = 2;
else if(c[0]=='N')	t = 3;
ans = 0;
memset(book,0,sizeof(book));
dfs(tn,tm,t);
if(ans==1)	printf("YES\n");
else printf("NO\n");
}
return 0;
}
void dfs(int x,int y,int t){
if(x==xn&&y==xm){
ans = 1;
return ;
}
for(int i=0;i<4;i++){
int tx,ty;
tx = x + d[t][i][0];
ty = y + d[t][i][1];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&(a[tx][ty]=='.'||a[tx][ty]=='X'||a[tx][ty]=='T')){
if(book[fun[t][i]][x][y]==1){
ans = -1;
return ;
}
else{
book[fun[t][i]][x][y]=1;
}
dfs(tx,ty,fun[t][i]);
book[fun[t][i]][x][y]=0;
if(ans!=0)	return ;
}
}
}

WAJUEJI which home strong!(nyoj 1100)

优先bfs
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n,m;
int d[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};//右下左上
struct mountain{
int x,y;
int money;
friend bool operator<(mountain a,mountain b)                //优先对列的定义
{

return a.money>b.money;
}
};
int bfs_priority(char a[][100],int book[][100],mountain first);
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
char a
[100];
int book
[100];
memset(book,0,sizeof(book));
mountain first;
for(int i=0;i<n;i++){
scanf("%s",a[i]);
for(int j=0;j<m;j++){
if(a[i][j]=='s'){
first.x=j;
first.y=i;
first.money=0;
}
}
}
book[first.y][first.x] = 1;
printf("%d\n",bfs_priority(a,book,first));
}
return 0;
}

int bfs_priority(char a[][100],int book[][100],mountain first){
priority_queue<mountain>Q;
Q.push(first);
while(!Q.empty()){   //注意不为空返回0
mountain temp;
temp = Q.top();
Q.pop();
for(int i=0;i<4;i++){
mountain t=temp;
t.x+=d[i][0];
t.y+=d[i][1];
if(t.x<0||t.x>=m||t.y<0||t.y>=n){
continue;
}
if(a[t.y][t.x]=='l'){
return t.money;
}
if(book[t.y][t.x]==0&&a[t.y][t.x]!='#'){
t.money += a[t.y][t.x]-'A'+1;
Q.push(t);
book[t.y][t.x] = 1;
}
}
}

return -1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: