dfs

其实玩游戏也得学程序

题目地址:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2465

只是用DFS练练手而已。(敲打)。


//head file

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//definition
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef struct
{
    int x;
    int y;
    int blood;    //在此地被打掉的血值
}PosType;



//type
typedef PosType SElemType;
typedef SElemType ElemType;
typedef int Status;

//struct
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stacksize;
}SqStack;


Status InitStack(SqStack *S);
Status GetTop(SqStack *S,ElemType *e);
Status Push(SqStack *S, ElemType e);
Status Pop(SqStack *S);
Status EmptyStack(SqStack *S);
Status StackClear(SqStack *S);
Status StackCpy(SqStack *des, SqStack *src);


char map[150][150];    //地图
int vis[150][150];
int min_blood,m_steps;    //最少的失血和最少的步骤数
PosType start, end;    //开始的坐标和结束的坐标
SqStack min_s; //用来存放最少失血量的路径
int m,n; //n为行数,m为列数

void MapTraverse(SqStack *s1, PosType cur, int blood, int steps);    //dfs搜索
Status PrintStack(SqStack *s);    //输出

int main(){
//    freopen("d:\\my.txt", "r", stdin);
    int i;
    int blood;
    SqStack s;
    InitStack(&s); InitStack(&min_s);    //栈的初始化

    while(scanf("%d %d", &n, &m), n != 0 || m != 0){
        blood = 0; min_blood = 0; m_steps = 0;   // 初始化
        memset(vis, 0, sizeof(n)); memset(map, 0, sizeof(map));
        start.x = 0; start.y = 0; end.x = n-1; end.y = m-1;
        start.x = 0;    //假设一开始没有敌人
        //读入地图
        for(i=0; i<n; i++)
            scanf("%s", map[i]);
        //遍历
        MapTraverse(&s, start, 0, 0);
        if(!PrintStack(&min_s)){
            printf("GAME OVER.\n");

        }
        printf("FINISH\n");
        StackClear(&s); StackClear(&min_s);    //清空栈
    }


  
    return 0;
}

void MapTraverse(SqStack *s, PosType cur, int blood, int steps){
    cur.blood = 0;    //假设当前没有敌人
    if(cur.x == end.x && cur.y == end.y && map[cur.x][cur.y] != 'X'){ //走到终点
        if(min_blood == 0 || min_blood > blood){
            min_blood = blood;
        //    printf("%d\n", min_blood);
            StackCpy(&min_s, s); m_steps = steps;
        }
        return;
    }
    if(cur.x <= n-1 && cur.x >=0 && cur.y <= m-1 && cur.y >=0) if( !vis[cur.x][cur.y] ){//对遇到的各种情况分析
        
        if(map[cur.x][cur.y] == 'X'){    //遇到墙壁
            return ;
        }
        else if(map[cur.x][cur.y] >= '0' && map[cur.x][cur.y] <= '9'){    //如果遇到的是数字
            blood += map[cur.x][cur.y]-'0';
            cur.blood = map[cur.x][cur.y] - '0';    //保存在此地的失血值
        }
        else if(map[cur.x][cur.y] == '.') ; //如果是.继续
        else if(map[cur.x][cur.y] == 0){ //遇到边界返回
            return;
        }

        Push(s, cur);  //将当前路径入栈
        /*
        if(cur.x == end.x && cur.y == end.y){ //走到终点
            if(min_blood == 0 || min_blood > blood){
                min_blood = blood;
                //    printf("%d\n", min_blood);
                StackCpy(&min_s, s); m_steps = steps;
            }
            return;
        }*/
        //每走一步steps+1, 失血+1
        //继续向上下左右遍历
        vis[cur.x][cur.y] = TRUE;
       
    /*    cur.x--; MapTraverse(s, cur, blood+1, steps+1);    //上
        cur.x++; cur.y++; MapTraverse(s, cur, blood+1, steps+1);    //右
        cur.y--; cur.x++; MapTraverse(s, cur, blood+1, steps+1);    //下    
        cur.x--; cur.y--; MapTraverse(s, cur, blood+1, steps+1);    //左
        cur.y++;*/
        cur.x++; MapTraverse(s, cur, blood+1, steps+1);    //
        cur.x -= 2; MapTraverse(s, cur, blood+1, steps+1);    //
        cur.x++; cur.y++; MapTraverse(s, cur, blood+1, steps+1);    //
        cur.y -= 2; MapTraverse(s, cur, blood+1, steps+1);    //
        cur.y++;
        
        vis[cur.x][cur.y] = FALSE;
        Pop(s);
    }
}


Status PrintStack(SqStack *s){
    if(s->base == s->top)
        return FALSE;
    ElemType *p = s->base+1, *pre = s->base;
    int i=1,j;
       //  pre = s->base;  //pre 用来保存上一个位置
    while(p != s->top){
        printf("%ds:(%d,%d)->(%d,%d)\n", i++, pre->x, pre->y, p->x, p->y);
        if(p->blood != 0) {
            
            for(j=0; j<p->blood; j++){
                printf("%ds:FIGHT AT (%d,%d)\n", i++, p->x, p->y);            
            }
        }
        p++; pre++;    //指向下一个结点
    }
    //因为终点时没有入栈,所以在这里要加一句输出    
    printf("%ds:(%d,%d)->(%d,%d)\n", i++, pre->x, pre->y, n-1, m-1);
    if (map[n-1][m-1] != '.'){    //判断终点是否有敌人
    //    printf("%c\n", map[n-1][m-1]);
        for(j=0; j<map[n-1][m-1]-'0'; j++){
            printf("%ds:FIGHT AT (%d,%d)\n", i++, n-1, m-1);            
        }
    }
        
    return TRUE;
}







Status InitStack(SqStack * S)
{
    S->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !S->base ) return ERROR;
    S->stacksize = STACK_INIT_SIZE;
    S->top = S->base;
    return OK;
}

Status StackClear(SqStack *S){
    S->top = S->base;
    return OK;
}

Status GetTop(SqStack * S, ElemType *e)
{
    if( S->top == S->base )    return ERROR;
    *e = *(S->top-1);
    return OK;
}

Status Push(SqStack *S, ElemType e)
{
    if( S->top - S->base >= S->stacksize )            
    {
        S->base = (ElemType *)realloc(S->base,(S->stacksize + STACKINCREMENT)*sizeof(ElemType));
        if( !S->base ) return ERROR;
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e;
    return OK;
}

Status Pop(SqStack *S)
{
    if( S->base == S->top )
        return ERROR;
    S->top--;
    return OK;
}

Status EmptyStack(SqStack *S)
{
    if( S->base == S->top )
        return OK;
    else
        return ERROR;
}

Status StackCpy(SqStack *des, SqStack *src){
    StackClear(des);
    ElemType *p;
    p = src->base;
    while(p != src->top){
        Push(des, *p++);
    }
    return OK;
}
原文地址:https://www.cnblogs.com/tanhehe/p/2883516.html