人工智能实验室寒假集训-Day4

题目链接

普及题:
http://acm.zzuli.edu.cn/problem.php?id=1991
提高题:
http://acm.zzuli.edu.cn/problem.php?id=1397

普及题

zzulioj 1991: 回形取数

按着题意模拟即可,有很多解决方法。
我的思路是:从左上角开始,沿着直线向下走,走到边界尽头向左拐,继续直走,走到边界尽头再左拐。直到所有路径都走过(即左拐后也无法继续走的时候)即可。可以用一个数组标记是否走过,或者用四个变量标记边界。

#include<bits/stdc++.h>
using namespace std;
int arr[205][205];
int vis[205][205];
int d[4] = {1,0,-1,0};
int f[4] = {0,1,0,-1};
// d,f 控制遍历的方向。
// 0时x轴坐标加一,y轴不变,相当于向下走 1:向右  2:向上  3:向左 
int main(){
	int m, n;
	cin >> m >> n;
	memset(vis, 0, sizeof(vis));
	for(int i = 0; i < m; i++){
		for(int j = 0; j < n; j++){
			scanf("%d",&arr[i][j]);
		}
	}
	int x = 0, y = 0, sign = 0, x1, y1;
	while(1){
		if(vis[x][y] == 0){
			printf("%d ",arr[x][y]);
			vis[x][y] = 1;
		}
		x1 = x + d[sign];
		y1 = y + f[sign];
		// 如果直走可以 
		if(x1 >= 0 && y1 >= 0 && x1 < m && y1 < n && vis[x1][y1] == 0){
			x = x1; y = y1;
		}else{		// 直走不可以就向左转弯 
			sign++;
			if(sign == 4) sign = 0;
			x1 = x + d[sign];
			y1 = y + f[sign];
			//如果左转弯可以 
			if(x1 >= 0 && y1 >= 0 && x1 < m && y1 < n && vis[x1][y1] == 0){
				x = x1; y = y1;
			}else{		//如果向左转弯也不可以就退出 
				break;
			}
		}
	}
} 

提高题

zzulioj 1397: 迷宫问题

题目要求只能向下或者向右走,只用考虑这两种情况就行,并且不需要用数组标记是否经过过,因为只向下或者向右走不会走重复的路。m,n都小于等于10,所以可以用dfs。
大致思路是:用char数组存地图信息,dfs遍历每条路径,遇到墙则不能经过,到终点时路径数加一。
不熟练的可以多找一点类似的题,或者在网上找一下相关代码。

#include<bits/stdc++.h>
using namespace std;
char arr[15][15];
int d[2] = {1,0};
int f[2] = {0,1};
int ans;

void dfs(int n, int m, int x, int y){
	//因为从0开始,所以终点是(n-1, m-1) 
	if(x == n-1 && y == m-1){
		ans++;
		return;
	}else{
		int x1, y1;
		for(int i = 0; i < 2; i++){
			x1 = x + d[i];
			y1 = y + f[i];
			// 判断该点是否在地图范围中,以及是否能够经过 
			if(x1 >= 0 && y1 >= 0 && x1 < n && y1 < m 
			 && arr[x1][y1] == '.'){
				dfs(n, m, x1, y1);
			} 
		}
	}
}

int main(){
	int t, m, n;
	cin >> t;
	while(t--){
		ans = 0;
		scanf("%d %d", &n, &m);
		for(int i = 0; i < n; i++){
			scanf("%s", arr[i]);
		}
		dfs(n, m, 0, 0);
		cout << ans << endl;
	}
} 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值