【集训day3】搜索(5/11)

Day3 搜索作业

A:
八皇后类似,但略有区别:不一定要放满n个棋子

(我随便码的……这都能一次过?!)
就按八皇后思路,每一层两种选择,不放棋子/在1-n列中合法的地方放棋子
然后cnt>n即return这个地方第一次没有写到,调试发现会死循环才补上的

#include<stdio.h>
int n,k,ans;
char map1[10][10];
int map[10][10];
int vis[10];//标记0-n列有无棋子 

void dfs(int cnt,int num){//层数,已经放了num个棋子 
	if(num==k){
		ans++;
		return;
	}
	if(cnt>n) return;
	dfs(cnt+1,num);
	for(int j=0;j<n;j++){
		if(vis[j]==0&&map[cnt][j]==0){
			vis[j]=1;
			dfs(cnt+1,num+1);
			vis[j]=0;
		} 
	}
}
int main()
{
	while(scanf("%d%d",&n,&k)==2&&n!=-1&&k!=-1){
		for(int i=1;i<=n;i++) scanf("%s",map1[i]);
		for(int i=1;i<=n;i++){
			for(int j=0;j<n;j++){
				if(map1[i][j]=='#') map[i][j]=0;
				else map[i][j]=1;
			}
		}
		ans=0;
		dfs(1,0);
		printf("%d\n",ans);
	}
	return 0;
}

B:
队列里放结构体的做法还不是很熟练,不过这回写下来就会了
然后总体很顺畅,但写出了两个bug
一是标记是否访问的问题,一开始没有写 !vis[sz][sx][sy] 这一条件,直接TLE
二是队列q的声明,一开始放在了最外面,但它应该放在每个样例,即while循环的里面,否则一直用的都是同一个队列,上一个样例遗留下来的队内元素影响到了下一个样例……也是一直WA的原因

#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
using namespace std;
char cube[35][35][35];
int vis[35][35][35];
struct node{
	int z,x,y;
	int step;
};

int dz[]={-1,1,0,0,0,0};
int dx[]={0,0,1,-1,0,0};
int dy[]={0,0,0,0,1,-1};


int main(){
	int l,r,c,sx,sy,sz;
	node t;
	while(scanf("%d%d%d",&l,&r,&c)==3&&l&&r&&c){
		queue<node>q;
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=l;i++){
			for(int j=1;j<=r;j++){
				for(int k=1;k<=c;k++){
					cin>>cube[i][j][k];
					//printf("%c",cube[i][j][k]);
					if(cube[i][j][k]=='S'){
						t.z=i;
						t.x=j;
						t.y=k;
						t.step=0;
						q.push(t);
					}
				}
				//printf("\n");
			}
		}
		int ok=0;
		while(!q.empty()){
			node now=q.front();
			q.pop();
			int nz=now.z;
			int nx=now.x;
			int ny=now.y;
			if(cube[nz][nx][ny]=='E'){
				cout<<"Escaped in "<<now.step<<" minute(s)."<<endl;
            	ok=1;
            	break;
			}
			for(int i=0;i<6;i++){
				node next;
				sx=next.x=nx+dx[i];
				sy=next.y=ny+dy[i];
				sz=next.z=nz+dz[i];
				next.step=now.step+1;
				if(sx<1||sy<1||sz<1||sx>r||sy>c||sz>l) continue;
				if(cube[sz][sx][sy]!='#'&&!vis[sz][sx][sy]){
					vis[sz][sx][sy]=1;
					q.push(next);
				}
			}
		}
		if(ok==0) cout<<"Trapped!"<<endl;
	}
	return 0;
} 

C:
农民要去抓牛。在一条笔直的路上,牛的位置为k,不动。农民从位置n出发,每次可以移动到位置n-1或n+1或2n,每次移动都花费1分钟,问抓到牛的最短时间

本来想用dp做,可是dp[i]=dp[i-1]+dp[i+1]+dp[2i]……由于dp[i+1]的存在,是倒推不了的
然后bfs一遍过

#include<stdio.h>
#include<queue>
using namespace std;
int vis[100005];
int main()
{
	queue<int>q;
	int n,k;
	scanf("%d%d",&n,&k);
	q.push(n);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		if(x==k){
			printf("%d",vis[x]);
			break;
		}
		int nx;

		nx=x-1;
		if(nx>=0&&nx<=100000&&vis[nx]==0){
			vis[nx]=vis[x]+1;
			q.push(nx);
		}
		nx=x+1;
		if(nx>=0&&nx<=100000&&vis[nx]==0){
			vis[nx]=vis[x]+1;
			q.push(nx);
		}
		nx=x*2;
		if(nx>=0&&nx<=100000&&vis[nx]==0){
			vis[nx]=vis[x]+1;
			q.push(nx);
		}
	}
	return 0;
}

K:
普通的走迷宫问题。BFS都快写完了才发现它要求输出路径,考虑到只是个5*5迷宫且路径唯一,DFS可行。

首先这题和P1101 单词方阵这题很像,关键点在于要把记录路径的结构体数组也作为参数传入DFS函数中,从而达到“只保存最短路径”的目的。
然后也出了一点小差错,比如说因为它是5*5迷宫,不知怎么的就觉得走5步就可以了……可能是因为参考了上面这道单词方阵,思路乱了。
一遍过啦。

#include<stdio.h>
#include<iostream> 
using namespace std;
int vis[7][7];
int map[7][7];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
struct node{
	int x,y;
};

void dfs(int ans,node c[],int x,int y){
	if(x==5&&y==5){
		for(int i=1;i<=ans-1;i++){
			printf("(%d, %d)\n",c[i].x-1,c[i].y-1);
		}
	}
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=1&&ny>=1&&nx<=5&&ny<=5){
		if(map[nx][ny]!=1&&!vis[nx][ny]){
			vis[nx][ny]=1;
			c[ans].x=nx;
			c[ans].y=ny;
			dfs(ans+1,c,nx,ny);	
		}
		}	
	}
}

int main()
{
	for(int i=1;i<=5;i++){
		for(int j=1;j<=5;j++){
			cin>>map[i][j];
		}
	}
	node c[30];
	vis[1][1]=1;
	c[1].x=1;
	c[1].y=1;
	dfs(2,c,1,1);
	return 0;
}

L:
做烂了,略

发布了28 篇原创文章 · 获赞 0 · 访问量 664

猜你喜欢

转载自blog.csdn.net/weixin_45561591/article/details/103946655