做了2小时,AC 5%,太强了
查看原帖
做了2小时,AC 5%,太强了
245579
holy楼主2023/2/12 04:38

我用的纯dfs,,,套了下模板,结果。。。忘记dfs复杂度高了,下面我想想改进方法,或者用Dijkstra试试

#include<iostream>
#include<cstdio> //scanf()
using namespace std;
int a[3010][3010], book[3010][3010], b[3010][3010];
int fly[3010][3010], ans = 3000;
int n, m, k;

void dfs(int x, int y, int step)
{
    int next[4][2] = { //方向数组, 循环得到下一步坐标
            {-1, 0}, //上
            {1, 0}, //下
            {0, -1}, //左
            {0, 1}}; //右

    //dfs第一步: 遍历
    int tx, ty; //临时变量
    for(int i = 0; i < 4; ++i) {
        tx = x + next[i][0]; //0表示每行第1个元素
        ty = y + next[i][1]; //1表示每行第2个元素
        //越界
        if(tx < 1 || ty < 1 || tx > n || ty > m)
            continue; //跳出本次循环
        //非障碍物且未走过
        if(a[tx][ty] != 0 && book[tx][ty] != 1) {
            book[tx][ty] = 1; //标记
            dfs(tx, ty, step + 1); //递归
            book[tx][ty] = 0; //取消标记
        }
    }
    //找到目标
    if(x == n && y == m) {
        ans = min(ans, step); //更新
        return; //返回上一步
    }
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%d", &a[i][j]); //读入数据
    int r, t;
    for(int i = 0; i < k; ++i) {
        scanf("%d%d", &r, &t);
        fly[r][t] = 1; //可飞行
    }
    book[1][1] = 1; //初始已走过

    //得到全程走的最小值
    dfs(1, 1, 0);

    //得到飞的最小值
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            if(fly[i][j] == 1) { //可飞
                if(a[i][j] != a[1][1]) //高度不同
                    dfs(i, j, 2);
                else //高度一样
                    dfs(i, j, 1);
            }
    cout<<ans;
    return 0;
}

2023/2/12 04:38
加载中...