搜索

BFS

eg.1
原题链接:https://ac.nowcoder.com/acm/contest/9986/I
AC代码:

#include
using namespace std;
const int N = 1000;

struct node{
	int x;
	int y;
	int step;
}s,g,Node;

int n,m,flag;
char mp[N][N];
int vis[N][N];

int X[5]={0, 0, 1, -1};
int Y[5]={1, -1, 0, 0};

bool judge(int x, int y){
	if(x < 1 || x > n || y < 1 || y > m || mp[x][y] == '#' || vis[x][y] == 1) return 0;
	else return 1;
}

void bfs(){
	queue<node>q;
	q.push(s);
    while(q.empty() != 1){
    	node top = q.front();
    	q.pop();
    	if(top.x == g.x && top.y == g.y){
    		flag = 1;
    		cout << top.step * 100 << endl;
    		return;
		}
		for(int i = 0; i < 4; i++){
			int newx = top.x + X[i];
			int newy = top.y + Y[i];
			if(judge(newx, newy)){
				Node.x = newx, Node.y = newy;
				Node.step = top.step+1;
				q.push(Node);
				vis[newx][newy] = 1;
			}
		}
	}
	
	if(flag == 0){
		cout << "-1" << endl;
		return;
	}	
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	while(cin >> n >> m){
	cin >> s.x >> s.y >> g.x >> g.y;
		flag = 0;
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				cin >> mp[i][j];
				vis[i][j] = 0;
			}
		}
		s.step = 0;
		bfs();
	}
	
	return 0;
}

eg.2 hdu1072
AC代码:

#include 
using namespace std;

int n, m, a, bx, by;
int mmap[10][10];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

struct node{
	int x;
	int y;
	int step;
	int time;
};

void bfs(){
	queue<node> q;
	node t = {bx, by, 0, 6};
	q.push(t);
	while(!q.empty()){
		node p;
		p = q.front();
		q.pop();
		for (int i = 0; i < 4; ++i){
			t.x = dx[i] + p.x;
			t.y = dy[i] + p.y;
			t.step = p.step + 1;
			t.time = p.time - 1;
			if(t.x >= 0 && t.x < n && t.y >= 0 && t.y < m && t.time > 0 && mmap[t.x][t.y] != 0){//0为墙 
				if(mmap[t.x][t.y] == 3){//到达终点 
					cout << t.step << endl;
					return ;
				}
				if(mmap[t.x][t.y] == 4){
					t.time = 6;
					mmap[t.x][t.y] = 0;
				}
				q.push(t);
			}
		}
	}
	cout << -1 << endl; 
	return ;
}

int main(){
	cin >> a;
	while(a--){
		cin >> n >> m;
		for (int i = 0; i < n; ++i){
			for (int j = 0; j < m; ++j){
				cin >> mmap[i][j];
				if(mmap[i][j] == 2) {
					bx = i;
					by = j;
				}
			}
		}
		bfs();
	}
	return 0;
}

DFS

eg.1hdu1010
知识点
1.曼哈顿距离、欧氏距离
2.奇偶剪枝
exter是偶数就能走到终点。
3.dfs是用递归实现的。那么如果我们找到了终点并且路数也符合,不能只是让 指示变量(flag)变值那么简单,还要在每次递归返回后面再加上一个判断,目的是终止查找,如果不这样做,就算找到了结果是YES我们也必须等到整个图全部被扫描完才可以结束程序,这样就增加了时间复杂度。

#include //DFS
using namespace std;
typedef long long ll;

int n, m, t, step, xs, ys, xe, ye, num;//xs,ys起点。xe,ye终点 
bool flag;
int dx[5] = {1, 0, 0, -1};//bfs和dfs都要写这一步
int dy[5] = {0, 1, -1, 0};
char mmap[8][8];

bool judge(int x, int y){//判断是否在地图里。bfs和dfs都要写 
	if(x >= 0 && x < n && y >= 0 && y < m) return 1;//可以=0 
	else return 0;
}

void dfs(int x, int y, int step){
	if(step == t && x == xe && y == ye) {
		flag = 1;
		return ;
	}
	if((abs(x - xe) + abs(y - ye)) > t - step) return ;//剪枝,该点到终点的距离大于所给的最小距离。
	if((abs(x - xe) + abs(y - ye)) % 2 != (t - step) % 2) return ;//奇偶剪枝 
	for (int i = 0; i < 4; ++i){
		int dxx = x + dx[i];
		int dyy = y + dy[i];
		if(judge(dxx, dyy) && mmap[dxx][dyy] != 'X'){//X是不能走的地方
			mmap[dxx][dyy] = 'X';//标记走过的地方为不可走的
			dfs(dxx, dyy, step + 1);
			mmap[dxx][dyy] = '.';//撤销上一步尝试。 
		}
	} 
} 

int main(){
	while(cin >> n >> m >> t){
		if(n == 0 && m == 0 && t == 0) break;
		num = 0;//最多可以走多少步 
		flag = 0;
		for (int i = 0; i < n; ++i){//读入迷宫地图
			for (int j = 0; j < m; ++j){
				cin >> mmap[i][j];	
				if(mmap[i][j] == 'S'){//找到起点 
					xs = i;
					ys = j; 
				}
				else if(mmap[i][j] == 'D'){
					xe = i;
					ye = j;
					num++;
				}
				else if (mmap[i][j] == '.'){
					num++;
				} 
			} 		 
		}
		mmap[xs][ys] = 'X';//因为不能回头走,所以把起点标记成不能走的路 
		if(num >= t) dfs(xs, ys, 0); 
		if(flag == 1) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
} 

eg.2 hdu1015
题意:
给定一个目标值target,再给你一个备选字符串(5~12个字符),要你在这个字符串里选5个出来,满足题中给定的等式,并且你选择的这5个字符组成的字符串必须是所有可能情况中按字典序最大的情况。
知识点:
1.打表:
意指对一些题目,通过打表技巧获得一个有序表或常量表,来执行程序某一部分,优化时间复杂度。这种算法也可用于在对某种题目没有最优解法时,用来得到分数的一种策略。
2.memset初始化字符数组。

#include 
using namespace std;

int n;
char str[25];
int s[25], f[25], flag[25];

bool cmp(char a, char b){
	return a > b;//降序排列 
}

int res(int v, int w, int x, int y, int z){
	return v - w*w + x*x*x - y*y*y*y + z*z*z*z*z;
}  

int dfs(int n, int len, int step){
	if(step == 5){
		if(res(f[0], f[1], f[2], f[3], f[4]) == n) return 1;
		else return 0;
	}
	for (int i = 0; i < len; ++i){
		if(flag[i]) continue;
		flag[i] = 1;
		f[step] = s[i];
		if(dfs(n, len, step + 1)) return 1;
		flag[i] = 0;
	}
	return 0;
}

int main(){
	memset(str, 'A', 20);
	while(cin >> n >> str){
		if(n == 0 && str[0] == 'E' && str[1] == 'N' && str[2] == 'D') break;
		int len = strlen(str);
		sort(str, str + len, cmp);//按字典序排序。因为题目要求按字典序从大到小。 sort默认升序,降序需要自己写函数 
		for (int i = 0; i < len; ++i){
			flag[i] = 0; 
			s[i] = str[i] - 'A' + 1;//保证每个字母的值都在1~26之间 
		}
		if(dfs(n, len, 0)){
			for (int i = 0; i < 5; ++i){
				printf("%c", f[i] + 'A' - 1);
			}
			cout << endl;
		}
		else cout << "no solution" << endl;	
	}
	return 0;
}

你可能感兴趣的:(排序,学习笔记,搜索)