有大佬能看看我 40 分 代码哪出问题了吗

P11228 [CSP-J 2024] 地图探险

Ahws_rwhy @ 2024-10-26 20:27:58

#include <bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n, m, k;
int x, y, d;
char mp[1001][1001];
int flag[1001][1001];
int ans;
signed main() {
    cin >> t;
    while (t--) {
        memset(flag,0,sizeof flag);
        ans = 0;
        cin >> n >> m >> k;
        cin >> x >> y >> d;
        int nowx = x, nowy = y;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                cin >> mp[i][j];
            }
        }
        while (k > 0) {
            if (d == 0) {
                k--;
                nowx = nowx, nowy = nowy + 1;
                if (nowx > n || nowy < 1 || nowx < 1 || nowy > m) {
                    d = (d + 1) % 4;
                    nowy = nowy - 1;
            //      continue;
                }
                if (mp[nowx][nowy] == '.' && d == 0 && flag[nowx][nowy] == 0) {
                    ans++;
                    flag[nowx][nowy] = 1;
                }
                if (mp[nowx][nowy] == 'x' && d == 0) {
                    d = (d + 1) % 4;
                    nowy = nowy - 1;
                }
            }
            if (d == 1) {
                k--;
                nowx = nowx + 1, nowy = nowy;
                if (nowx > n || nowy < 1 || nowx < 1 || nowy > m) {
                    d = (d + 1) % 4;
                    nowx = nowx - 1;
                //  continue;
                }
                if (mp[nowx][nowy] == '.' && d == 1 && flag[nowx][nowy] == 0) {
                    ans++;
                    flag[nowx][nowy] = 1;
                }
                if (mp[nowx][nowy] == 'x' && d == 1) {
                    d = (d + 1) % 4;
                    nowx = nowx - 1;
                }
            }
            if (d == 2) {
                k--;
                nowx = nowx, nowy = nowy - 1;
                if (nowx > n || nowy < 1 || nowx < 1 || nowy > m) {
                    d = (d + 1) % 4;
                    nowy = nowy + 1;
                //  continue;
                }
                if (mp[nowx][nowy] == '.' && d == 2 && flag[nowx][nowy] == 0) {
                    ans++;
                    flag[nowx][nowy] = 1;
                }
                if (mp[nowx][nowy] == 'x' && d == 2) {
                    d = (d + 1) % 4;
                    nowy = nowy + 1;
                }
            }
                if (d == 3) {
                    k--;
                    nowx = nowx - 1, nowy = nowy;
                    if (nowx > n || nowy < 1 || nowx < 1 || nowy > m) {
                        d = (d + 1) % 4;
                        nowx = nowx + 1;
                    //  continue;
                    }
                    if (mp[nowx][nowy] == '.' && d == 3 && flag[nowx][nowy] == 0) {
                        ans++;
                        flag[nowx][nowy] = 1;
                    }
                    if (mp[nowx][nowy] == 'x' && d == 3) {
                    //  k--;
                        d = (d + 1) % 4;
                        nowx = nowx + 1;
                    }
                }
        }
        if(1 <= x && x <= n && 1 <= y && y <= m) ans++;
        cout << ans << endl;
    }
    return 0;
}

by hyl2718281828 @ 2024-10-26 20:34:12

感觉可能是ans算重了,但不确定


by hyl2718281828 @ 2024-10-26 20:35:21

我建议你定义一个常量数组,专门存横纵坐标变化量,直接一个循环就可以跑四种情况


by Ahws_rwhy @ 2024-10-26 20:35:48

@hyl2718281828 能讲讲那算重了吗


by hyl2718281828 @ 2024-10-26 20:36:20

还有就是ans没必要一个个加,容易出错,你可以只记录走过的点,最后遍历一遍flag数组加上去,绝对不会错


by hyl2718281828 @ 2024-10-26 20:37:41

另外,对于不可以走的点,我觉得在走到那之前就应该把它排除。可以专门写一个check函数判断是否可行,代码会简洁很多


by hyl2718281828 @ 2024-10-26 20:39:42

还有他转向是单独算一步的,你是不是没算进去

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+1;
const int dx[] = {0,1,0,-1}, dy[] = {1,0,-1,0};
int T,n,m,k,ans;
char G[N][N];
bool vis[N][N];
bool check(int x,int y) {return x > 0 && x <= n && y > 0 && y <= m && G[x][y] == '.';}
int main() {
    freopen("explore.out","w",stdout);
    scanf("%d",&T);
    while (T--) {
        int x,y,d;
        scanf("%d%d%d",&n,&m,&k);
        scanf("%d%d%d",&x,&y,&d);
        for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> G[i][j];
        vis[x][y] = 1;
        for (int r = 1; r <= k; r++) {
            int _x = x+dx[d], _y = y+dy[d];
            if (check(_x,_y)) {
                vis[_x][_y] = 1;
                x = _x;
                y = _y;
            } else d = (d+1)%4;
        }
        for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) ans += vis[i][j];
        printf("%d\n",ans);
        ans = 0;
        memset(vis,0,sizeof(vis));
    }
    return 0;
}

by hyl2718281828 @ 2024-10-26 20:40:22

多打了一个freopen


by Ahws_rwhy @ 2024-10-26 20:41:19

@hyl2718281828 我觉得算进去了呀,每次if 里面 的次数都减 1 了呀?


by hyl2718281828 @ 2024-10-26 20:45:50

哦我好像知道了,你走到障碍之后再退回来多算了一步,因为只有k步,你这里多占了一步,没加回去,后面ans就少了


by Ahws_rwhy @ 2024-10-26 20:49:13

@hyl2718281828 现在过了,谢谢(猫的,出发点未打标记)


| 下一页