尿酸606 2020-05-23 20:52 采纳率: 0%
浏览 24
已结题

求一下该代码时间复杂度和空间复杂度的分析

#include<stdio.h>
#define N (5)
#include<stack>
using namespace std;
bool mark[N][N];




typedef struct Pos{
    //位置结构体
    int i, j;
    void set(int i, int j)
    {
        this->i = i;
        this->j = j;
    }
}POS;


bool IsPos(const int maze[][N], int i, int j)
{//判断迷宫位置是否合法及是否已经走过
    if (i >= 0 && i < N && j >= 0 && j < N &&maze[i][j] == 0 &&mark[i][j] == true)
        return true;
    else
        return false;
}




bool enable(const int maze[][N])
{//判断迷宫能否从左上角走到右下角
    if(maze[0][0] == 1 || maze[N-1][N-1] == 1) return false;//左上角和右下角为1则迷宫一定不可通
    stack<POS> S;
    
    for(int i=0;i<N;++i)//初始标记数组
    {
        for(int j=0;j<N;++j)
            mark[i][j] = true;
    }
    
    mark[0][0] = false;//设置左上角已经走过
    POS ps; ps.set(0, 0);
    S.push(ps);


    int pos[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1 };
    
    while (!S.empty())
    {
        ps = S.top();
        bool is = false;
        for (int k = 0; k < 4; ++k)
        {
            if (IsPos(maze, ps.i + pos[k][0], ps.j + pos[k][1]))//依次判断迷宫4个方向的走位
            {
                ps.i += pos[k][0]; ps.j += pos[k][1];
                if(ps.i == N-1 && ps.j ==N-1)//如果已经走到右下角,返回true
                    return true;
                    
                mark[ps.i][ps.j] = false;
                S.push(ps);
                is = true;
                break;
            }
        }
        if (!is)
        {
            S.pop();
        }
            
    }
    return false;//没有走通,返回false
}


void show(int maze[][N])
{//打印迷宫方便调试
    for(int i=0;i<N;++i)
    {
        for(int j=0;j<N;++j)
            printf("%d ", maze[i][j]);
        putchar('\n');
    }
}


void exchange(int maze[][N], int n)
{//将n转换成数组保存的迷宫,0为路,1为墙
    for(int i=N-1;i>=0;--i)
    {
        for(int j=N-1;j>=0;--j)
        {
            maze[i][j] = n&1;
            n>>=1;
        }
            
    }




/*取余法将n转换为数组保存的迷宫
    stack<int> S;
    
    while(n)
    {
        S.push(n % 2);
        n /= 2;
    }
    
    while(S.size()< N*N)
        S.push(0);
    
    int cnt=0;
    int i,j;
    i=j=0;
    
    while(!S.empty())
    {
        maze[i][j] = S.top();
        j++;
        ++cnt;
        if(cnt == N)
        {
            j=0;++i;
            cnt = 0;
        }
        S.pop();
    }
    */
}


bool IsPos2(const int maze[][N], int i, int j)
{//判断位置i、j迷宫是否可通
    if (i >= 0 && i < N && j >= 0 && j < N &&maze[i][j] == 0)//判断该位置是否可通
        return true;
    else
        return false;
}


bool search( int maze[][N])
{
    //判断按右手法则搜索A、B能否相遇,相遇返回true否则返回false
    int pos[4][2] = { 0, 1, -1, 0, 0, -1, 1, 0 };
                        
    POS ps1,ps2;
    
    ps1.set(0,0);//初始化A位置
    ps2.set(N-1,N-1);//初始化B位置
    
    int d1,d2;//d1、d2表示方向,0表示向右,1向上,2向左,3向下
    
    d1=3;d2=1;//初始化方向,其中d1为A的方向,d2为B的方向,初始时A向下,B向上
    
    while(1)
    {
        do{ 
            if(IsPos2(maze, ps1.i+pos[d1][0],ps1.j+pos[d1][1]))//按当前方向A是否可以走到下一个位置
            {
                ps1.i+=pos[d1][0];ps1.j+=pos[d1][1];//按当前方向A可以走到下一个位置,更新位置
                d1 = (d1-1+4)%4;//更新方向为当前方向的右手边方向
                break;//A走了一步,跳出循环
            }
            else//按当前方向A不可以走到下一个位置(有墙或者出了迷宫)
                d1 = (d1+1+4)%4;//按逆时针更新方向
        }while(1);
        
        do{//同理对B进行上述操作
            if(IsPos2(maze, ps2.i+pos[d2][0],ps2.j+pos[d2][1]))
            {
                ps2.i+=pos[d2][0];ps2.j+=pos[d2][1];
                d2 = (d2-1+4)%4;
                break;
            }
            else
                d2 = (d2+1+4)%4;
        }while(1);
        
        if(ps1.i == ps2.i && ps1.j == ps2.j)//A、B相遇,返回1
            return 1;
        
        if((ps1.i == N -1 && ps1.j ==N-1) || (ps2.i == 0 && ps2.j==0) )//A、B有一个先到达终点,不可能相遇,返回0
            return 0;
    }
}
int count()
{//计数函数,返回A、B相遇的迷宫模式数量
    int maze[N][N];
    int mazeI;
    int cnt = 0;
    for(mazeI=0; mazeI< (1<<N*N); ++mazeI)//对所有可能的迷宫进行检验(总共2^(N*N)个迷宫)
    {
        exchange(maze, mazeI);  
            if(enable(maze))
            {
                if(search(maze))
                    ++cnt;      
            }
    }
    return cnt;
}
int main()
{
    printf("当n=%d时,一共有%d种满足条件的迷宫。\n",N,count());
}
  • 写回答

2条回答 默认 最新

  • 波塞冬的祝福 2020-05-24 07:04
    关注
    时间复杂度 一般是看for循环有没有嵌套..执行了几次..
    
    评论

报告相同问题?