poj 3009 深搜

链接 http://poj.org/problem?id=3009


题意:打冰球游戏,


如图,S为起点,G为目标点。阴影为石块,冰球从起点开始往四个方向扔出,紧挨着石块时不能往那个方向扔出(在图中,S处起始不能往右),在一个方向上一直直线运动,要么出界,要么打中一个石块,打中石块后,那个石块会被击碎,然后冰球会停止在石块旁边的空格处,通过一直这样做,目的是能扔到G点,结束游戏。


在这题中,扔出一次后,就会对整张图产生影响(有石块会被击碎),所以肯定要用先深搜索。


ac代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#define INF 123123123
#define MAX_INDEX 24
using namespace std;


int graph[MAX_INDEX][MAX_INDEX];
int direction[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int start_x,start_y,goal_x,goal_y,ans;
int n,w,h;
int dfs(int now_x,int now_y,int already);
bool ISblock(int now_x,int now_y);
bool ISgoal(int now_x,int now_y);
bool IN(int now_x,int now_y);


void debug_graph();
int main()
{
    while(cin >> h >> w)
    {
        if(!h&&!w)
            break;
        for(int i=0; i<w; i++)
        {
            for(int j=0; j<h; j++)
            {
                scanf("%d",&graph[i][j]);
                if(graph[i][j] == 2)
                {
                    start_x = i;
                    start_y = j;
                }
                if(graph[i][j] == 3)
                {
                    goal_x = i;
                    goal_y = j;
                }
            }
        }
        //printf("goal_x = %d,goal_y = %d\n",goal_x,goal_y);
        //cout << "after cin ,";
        //debug_graph();
        ans = INF;
        int result = dfs(start_x,start_y,0);
        if(result>=0&&result<=10)
            printf("%d\n",result);
        else
            printf("-1\n");
    }
    return 0;
}
int dfs(int now_x,int now_y,int already)
{
    if(now_x==goal_x&&now_y==goal_y)
        return already;
    int temp_x,temp_y;
    int final_ret = INF;
    for(int i=0; i<4; i++)
    {
        if(ISgoal(now_x+direction[i][0],now_y+direction[i][1]))
        {
            return already+1;
        }
        if(!ISblock(now_x+direction[i][0],now_y+direction[i][1]))
        {
            temp_x = now_x+direction[i][0];
            temp_y = now_y+direction[i][1];
            while(IN(temp_x,temp_y)&&!ISgoal(temp_x,temp_y)&&!ISblock(temp_x,temp_y))
            {
                temp_x += direction[i][0];
                temp_y += direction[i][1];
            }
            if(!IN(temp_x,temp_y))
                ;
            else if(ISgoal(temp_x,temp_y))
            {
                return already+1;
            }
            else if(ISblock(temp_x,temp_y))
            {
                graph[temp_x][temp_y] = 0;
                //cout << "after knock (" << temp_x <<"," <<temp_y<<"),";
                //debug_graph();
                temp_x -= direction[i][0];
                temp_y -= direction[i][1];
                //cout << "i am in (" <<temp_x << "," << temp_y <<  ")" << endl;
                int ret;
                if(already<=9)
                    ret = dfs(temp_x,temp_y,already+1);
                else
                    ret = 11;
                graph[temp_x+direction[i][0]][temp_y+direction[i][1]] = 1;
                //cout << "after change back (" << temp_x+direction[i][0] << "," << temp_y+direction[i][1] << "),";
                //debug_graph();
                if(ret<final_ret)
                    final_ret = ret;
            }
        }
    }
    return final_ret;
}
bool IN(int now_x,int now_y)
{
    return now_x>=0&&now_x<w&&now_y>=0&&now_y<h;
}
bool ISblock(int now_x,int now_y)
{
    if(IN(now_x,now_y))
        return graph[now_x][now_y] == 1;
    return false;
}


bool ISgoal(int now_x,int now_y)
{
    return now_x == goal_x && now_y == goal_y;
}
void debug_graph()
{
    cout << " graph is \n";
    for(int i=0;i<w;i++)
    {
        for(int j=0;j<h;j++)
            printf("%d ",graph[i][j]);
        printf("\n");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值