题目链接
普及题:
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;
}
}