hud 3713

题目大意:两张图,都是6*6,同时操纵两张图上的球(它们的运动都是相同的,如果其中有一个被挡住那么那个求就不会动),题目下面有一张表,会告诉你地图上的数字变为二进制之后每一位的意义;

分析:非常蛋疼的BFS,没有什么技术含量,就是写起来非常麻烦非常消耗时间,这题目是我们在准备牡丹江regional时组队合练出的题目,当时我们错误的估计了这题目的难度没敲。。。感觉如果早点写这题的话应该可以4题的,以下是AC代码:

/*Problem : 3713 ( Double Maze )     Judge Status : Accepted
RunId : 11825237    Language : C++    Author : Burglar
Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta*/
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <queue>
#define MAXN 10005
#define N 8
using namespace std;
int map_first[N][N];
int map_second[N][N];
int judge[N][N][N][N];//标记状态
int move_step[4][2] = {{1, 0}, {0, -1}, {0, 1}, {-1, 0}};//保证字典序最小
struct Node
{
    int x1, x2, y1, y2;//两张图上面的球的坐标
    int dir;//方向
    int qian;//记录前驱,用于递归输出;
}Q[MAXN];//队列的长度其实最多也就6 * 6 * 6 * 6
struct Point
{
    int x, y;
};
Point first_star, second_star, first_end, second_end;
char Dir(int i)
{
    if(i == 0) return 'D';
    else if(i == 1) return 'L';
    else if(i == 2) return 'R';
    else
        return 'U';
}
void print(int i)//递归输出
{
    if(i == -1) printf("-1");
    if(i > 0) print(Q[i].qian);
    if(i > 0) printf("%c",Dir(Q[i].dir));
}
void input()//输入第二张图
{
    for(int i = 1; i <= 6; i++)
    {
        for(int j = 1; j <= 6; j++)
        {
            scanf("%d",&map_second[i][j]);
            if( (map_second[i][j] >> 5) & 1 )
            {
                second_star.x = i;
                second_star.y = j;
            }
            if( (map_second[i][j] >> 6) & 1 )
            {
                second_end.x = i;
                second_end.y = j;
            }
        }
    }
}
void copy_map()//把第二张图拷贝给第一张图
{
    for(int i = 1; i <= 6; i++)
    {
        for(int j = 1; j <= 6; j++)
        {
            map_first[i][j] = map_second[i][j];
        }
    }
    first_star = second_star;
    first_end = second_end;
}
bool in_map(int x, int y)//判断点在不在图里面
{
    if(1 <= x && x <= 6 && 1 <= y && y <= 6) return true;
    return false;
}
bool first_not_hole(int x, int y)//判断某个点是不是洞
{
    if( (map_first[x][y] >> 4) & 1) return true;
    return false;
}
bool second_not_hole(int x, int y)
{
    if( (map_second[x][y] >> 4) & 1) return true;
    return false;
}
bool first_canmove(int x, int y, int dir)//对于某个点可不可以往dir方向移动
{
    if( ((map_first[x][y] >> 0) & 1 ) && dir == 1) return false;
    if( ((map_first[x][y] >> 1) & 1 ) && dir == 0) return false;
    if( ((map_first[x][y] >> 2) & 1 ) && dir == 2) return false;
    if( ((map_first[x][y] >> 3) & 1 ) && dir == 3) return false;
    return true;
}
bool second_canmove(int x, int y, int dir)
{
    if( ((map_second[x][y] >> 0) & 1 ) && dir == 1) return false;
    if( ((map_second[x][y] >> 1) & 1 ) && dir == 0) return false;
    if( ((map_second[x][y] >> 2) & 1 ) && dir == 2) return false;
    if( ((map_second[x][y] >> 3) & 1 ) && dir == 3) return false;
    return true;
}
int BFS()//广搜
{
    int now, len;
    memset(judge, 0, sizeof(judge));
    memset(Q, 0, sizeof(Q));
    Node last, next;
    next.x1 = first_star.x;
    next.y1 = first_star.y;
    next.x2 = second_star.x;
    next.y2 = second_star.y;
    next.dir = -1;
    next.qian = -1;
    judge[next.x1][next.y1][next.x2][next.y2] = 1;
    now = 0, len = 1;
    Q[now] = next;
    while(now < len)
    {
        last = Q[now];
        now++;
        if( ( (map_first[last.x1][last.y1] >> 6) & 1 )&& ( (map_second[last.x2][last.y2] >> 6) & 1 ) )//判断是否到终点
        {
            return (now - 1);
            break;
        }
        for(int i = 0; i < 4; i++)
        {
            next = last;
            if(first_canmove(last.x1, last.y1, i))
            {
                next.x1 = last.x1 + move_step[i][0];
                next.y1 = last.y1 + move_step[i][1];
                if(!first_not_hole(next.x1, next.y1) || !in_map(next.x1, next.y1)) continue;
            }
            if(second_canmove(last.x2, last.y2, i))
            {
                next.x2 = last.x2 + move_step[i][0];
                next.y2 = last.y2 + move_step[i][1];
                if(!second_not_hole(next.x2, next.y2) || !in_map(next.x2, next.y2)) continue;
            }
            if(!judge[next.x1][next.y1][next.x2][next.y2])
            {
                judge[next.x1][next.y1][next.x2][next.y2] = 1;
                next.dir = i;
                next.qian = now - 1;
                Q[len] = next;
                len++;
            }
        }
    }
    return -1;
}
int main()
{
    int ans, case_num;
    scanf("%d",&case_num);
    for(int i = 1; i <= 6; i++)
    {
        for(int j = 1; j <= 6; j++)
        {
            scanf("%d",&map_first[i][j]);
            if( (map_first[i][j] >> 5) & 1)
            {
                first_star.x = i;
                first_star.y = j;
            }
            if( (map_first[i][j] >> 6) & 1)
            {
                first_end.x = i;
                first_end.y = j;
            }
        }
    }
    case_num--;
    while(case_num--)
    {
        input();
        print(BFS());
        printf("\n");
        copy_map();
    }
    return 0;
}

各位大神们看完就不要纠结我的函数命名了。。比较丑 我的代码风格还在成型中。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值