其实玩游戏也得学程序

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

可以用BFS。。

只是用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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值