Topcoder SRM646 div1 600 bfs+剪枝

因为只有47个blocks,所以现在小范围内,即在-50 <= x <= 50,-50 <= y <= 50内进行bfs,之后尽量让点向右走,记录最大值。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>
#include <iomanip>

#pragma comment(linker,"/STACK:1024000000");
#define EPS (1e-6)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 1000000007

using namespace std;

struct P
{
    int x,y,k;
};

queue<P> q;

map<pair<int,int>,int> M;

class TheGridDivOne
{
public :
    int find(vector <int> x, vector <int> y, int k)
    {
        q.push((P){0,0,0});

        M.insert( pair<pair<int,int>,int> (pair<int,int>(0,0),0));

        P f,s;

        int i , n;
        n = x.size();

        int Max = 0;

        map<pair<int,int>,int>::iterator it;

        while(q.empty() == false)
        {
            f = q.front();
            q.pop();

            if(k-f.k+f.x <= Max)
                continue;

            Max = max(Max,f.x);

            it = M.find(pair<int,int>(f.x,f.y));

            if(it->second < f.k)
                continue;

            int U = Mod,D = -Mod,L = -Mod,R = Mod;
            s = f;
            for(i = 0; i < n; ++i)
            {
                if(x[i] == s.x && y[i] > s.y)
                    U = min(U,y[i]);
                if(x[i] == s.x && y[i] < s.y)
                    D = max(D,y[i]);

                if(y[i] == s.y && x[i] > s.x)
                    R = min(R,x[i]);
                if(y[i] == s.y && x[i] < s.x)
                    L = max(L,x[i]);
            }

            s.y = f.y,s.x = min(f.x+k-f.k,R-1),s.k = f.k+s.x-f.x;

            it = M.find(pair<int,int>(s.x,s.y));

            if(it == M.end())
            {
                q.push(s);
                M.insert( pair<pair<int,int>,int> (pair<int,int>(s.x,s.y),s.k));
            }
            else if(it->second > s.k)
            {
                q.push(s);
                it->second = s.k;
            }

            for(i = f.x-1; i > max(f.x-2,L); --i)
            {
                s.x = i,s.y = f.y,s.k = f.k + f.x-i;

                it = M.find( pair<int,int>(s.x,s.y) );

                if(s.k > k)
                    break;

                if(it == M.end())
                {
                    M.insert( pair<pair<int,int>,int> (pair<int,int>(s.x,s.y),s.k));
                    q.push(s);
                }
                else if(it->second > s.k)
                {
                    it->second = s.k;
                    q.push(s);
                }
            }

            for(i = f.y+1; i < min(f.y+2,U); ++i)
            {
                s.x = f.x,s.y = i,s.k = f.k + i-f.y;

                if(s.k > k)
                    break;

                it = M.find( pair<int,int>(s.x,s.y));

                if(it == M.end())
                {
                    M.insert( pair<pair<int,int>,int> (pair<int,int>(s.x,s.y),s.k));
                    q.push(s);
                }
                else if(it->second > s.k)
                {
                    it->second = s.k;
                    q.push(s);
                }
            }

            for(i = f.y-1; i > max(f.y-2,D); --i)
            {
                s.x = f.x,s.y = i,s.k = f.k + f.y-i;

                if(s.k > k)
                    break;

                it = M.find( pair<int,int>(s.x,s.y));

                if(it == M.end())
                {
                    M.insert( pair<pair<int,int>,int> (pair<int,int>(s.x,s.y),s.k));
                    q.push(s);
                }
                else if(it->second > s.k)
                {
                    it->second = s.k;
                    q.push(s);
                }
            }

            if(f.k <= 50)
            {
                for(i = f.x+1; i < min(f.x+2,R); ++i)
                {
                    s.x = i,s.y = f.y,s.k = f.k + i-f.x;

                    it = M.find( pair<int,int>(s.x,s.y) );

                    if(s.k > k)
                        break;

                    if(it == M.end())
                    {
                        M.insert( pair<pair<int,int>,int> (pair<int,int>(s.x,s.y),s.k));
                        q.push(s);
                    }
                    else if(it->second > s.k)
                    {
                        it->second = s.k;
                        q.push(s);
                    }
                }
            }

        }
        return Max;
    }
};
时间: 2024-12-27 10:25:38

Topcoder SRM646 div1 600 bfs+剪枝的相关文章

POJ 3278 Catch That Cow(BFS 剪枝)

题目链接:http://poj.org/problem?id=3278 这几次都是每天的第一道题都挺顺利,然后第二道题一卡一天. = =,今天的这道题7点40就出来了,不知道第二道题在下午7点能不能出来.0 0 先说说这道题目,大意是有个农夫要抓牛,已知牛的坐标,和农夫位置.而且农夫有三种移动方式,X + 1,X - 1,X * 2,问最少几步抓到牛. 开始认为很简单的,三方向的BFS就能顺利解决,然后在忘开标记的情况下直接广搜,果然TLE,在你计算出最少位置之前,牛早跑了. 然后反应过来开标记

SPOJ 206 BITMAP(BFS+剪枝)

SPOJ 206 BITMAP(BFS+剪枝) ACM 题目地址:SPOJ 206 BITMAP 题意: 给出一个矩阵,有黑白点,计算每个点离最近的白点的距离,p1=(i1,j1) and p2=(i2,j2),距离d(p1,p2)=|i1-i2|+|j1-j2|. 分析: 有剪枝的BFS,如果从黑色的开始进行BFS最近的白色,复杂度是O(n^4),复杂度无法接受. 于是想把黑色白色分开记录下来,然后两遍for,发现复杂度不变... 从黑色开始搜,如果要记忆化的话,貌似很麻烦,但是我们可以从白色

HDU-1226 超级密码 (BFS+剪枝)

Problem Description Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:密 码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足 条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.注意:由于宝藏的历史久远,当时的系统最多只能

ppoj 3278搜索bfs+剪枝

http://poj.org/problem?id=3278 大致题意: 给定两个整数n和k 通过 n+1或n-1 或n*2 这3种操作,使得n==k 输出最少的操作次数 解题思路: 说实话,要不是人家把这题归类到BFS,我怎么也想不到用广搜的= = 自卑ing... 水题水题,三入口的BFS 注意的地方有二: 1.  由于用于广搜的 队列数组 和 标记数组  相当大,如果定义这两个数组时把它们扔到局部去,编译是可以的,但肯定执行不了,提交就等RE吧= = 大数组必须开为 全局 ...常识常识.

hdu 5040 优先队列BFS+剪枝

(北京网络赛09题)题意:给一矩阵(图),里面有起点,终点,还有探照灯(每个有初始朝向,每秒顺时针转90度),前面有灯或者自己被灯照着,移动就要花3秒,求起点到终点最短时间. 用一个数组三维数组记录一下,用来当前位置当前时间%4有没有灯,然后优先队列(时间短的在前面),搜索即可.考虑到可以来回走或者原地等,不能简单判重剪枝:每个地方最多是4种状态!就是4秒之后就全图状态回到一样!所以若当前状态(时间%4)下来过就不用来了. #include<iostream> #include<vect

HDU 2433 (最短路+BFS+剪枝)

http://acm.hdu.edu.cn/showproblem.php?pid=2433 这个问题因为路径都是1,所以可以用bfs遍历 可以看这几篇文章讲解: http://blog.csdn.net/panyanyany/article/details/7215069 (这篇代码非常清晰,而且效率很高) http://www.cppblog.com/keroro/archive/2013/05/27/200622.html?opt=admin 1 #include <cstdio> 2

HDU 5652 India and China Origins 二分优化+BFS剪枝

题目大意:给你一个地图0代表可以通过1代表不可以通过.只要能从第一行走到最后一行,那么中国与印度是可以联通的.现在给你q个点,每年风沙会按顺序侵蚀这个点,使改点不可通过.问几年后中国与印度不连通.若一直联通输出-1. 题目思路:看数据这道题就是卡时间的,我们的基本思路是每当风沙侵蚀一个点,我们就进行一次广搜,看看图上下是否联通,我们应尽可能的去优化这个过程. 所以我们可以在遍历年的时候用二分查找: 若当年图可以上下联通,则继续向右查找 若当年图上下无法联通,则向左查找 剪枝: 为了省时间我们应该

Poj1324(BFS+剪枝)

剪枝好题. 题目大意: 给一个地图,有一条蛇,给定从头到尾的各个点的坐标,地图上有些点是不能走的,然后就是跟以前玩过的贪吃蛇的规则一样了,蛇头不能碰到自己,问至少要多少步才能让蛇头从起点到达终点.地图长宽都是20以内,蛇长范围(2~8) 思路: 求最少步数,用bfs,图并不大,但是需要记录蛇的状态,还要判断重复.仔细观察,并不需要记录整个蛇各个点的坐标,也不需要把地图hash当做状态.我们要记录的状态无非就是蛇的位置. 那么其实也就是蛇头的坐标+蛇尾的相互关系.因为蛇是一个整体,身体的每一个部分

POJ 3126 Prime Path (BFS+剪枝)

题目链接:传送门 题意: 给定两个四位数a,b,每次可以改变a的任意一位,并且确保改变后的a是一个素数. 问最少经过多少次改变a可以变成b. 分析: BFS,每次枚举改变的数,有一个剪枝,就是如果这个改变的数之前已经得到过了, 就没有必要继续变回它了. 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue&g