zoukankan      html  css  js  c++  java
  • POJ 2922 Honeymoon Hike (dfs+二分答案+区间枚举)

    题意:给定一个n*n地图和高度,一个人从左上角地图开始,需要走到右下角的地图,问他走的路程中所到达的最大高度和最小高度的差最小是多少。

    思路:二分答案,对于每一个高度差,可以用dfs或bfs检验是否能够到达目的地,如果对每个高度差,用dfs,每次传以前的最大和最小高度,然后在更新,这样检验会超时,于是可以改用枚举高度区间的办法来缩减时间(想了半天没想出来....)。总的来所,一个不错的搜索题目。

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 105;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    #define SET_NODE(no,a,b) {no.x=a;no.y=b;}

    typedef
    struct{
    int x,y;
    }Node;

    Node t_node;
    int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
    int n,tt,ans,limit,low,high;
    int map[MAXN][MAXN];
    bool visit[MAXN][MAXN];

    bool _is(const int& x,const int& y)
    {
    if(x<0 || x>=n)
    return false;
    if(y<0 || y>=n)
    return false;
    return true;
    }
    int init()
    {
    CLR(visit,
    0);
    return 0;
    }
    int input()
    {
    IN(n);
    for(int i = 0; i < n; ++i)
    for(int j = 0; j < n; ++j)
    IN(map[i][j]);
    return 0;
    }
    /*
    bool bfs(const int& limit)
    {
    int x,y,i,j,tmp,high,low;
    queue<Node> que;
    Node node;
    CLR(visit,0);
    // initialize the queue
    while(!que.empty())
    que.pop();
    visit[0][0] = true;
    SET_NODE(t_node,0,0);
    que.push(t_node);
    low = high = map[0][0];
    // while loop
    cout<<limit<<endl;
    while(!que.empty())
    {
    node = que.front();
    que.pop();
    if(node.x == n-1 && node.y == n-1)
    return true;
    for(i = 0; i < 4; ++i)
    {
    x = node.x + dir[i][0];
    y = node.y + dir[i][1];
    if(_is(x,y) && !visit[x][y])
    {
    t_node.low = MIN(low,map[x][y]);
    t_node.high = MAX(high,map[x][y]);
    if(high - low > limit)
    continue;
    SET_NODE(t_node,x,y);
    visit[x][y] = true;
    que.push(t_node);
    }
    }
    }
    return false;
    }
    */
    bool dfs(const int& x,const int& y)
    {
    int a,b,h,l;
    if(map[x][y] > high || map[x][y] < low)
    return false;
    if(x == n-1 && y == n-1)
    return true;
    visit[x][y]
    = true;
    for(int i = 0; i < 4; ++i)
    {
    a
    = x + dir[i][0];
    b
    = y + dir[i][1];
    if(!visit[a][b] && _is(a,b))
    if(dfs(a,b))
    return true;
    }
    return false;
    }
    int work()
    {
    int b_high,b_low,b_mid;
    int i,j,tmp;
    b_high
    = -1;
    b_low
    = INF;
    for(i = 0; i < n; ++i)
    for(j = 0; j < n; ++j)
    {
    b_high
    = MAX(b_high,map[i][j]);
    b_low
    = MIN(b_low,map[i][j]);
    }
    b_high
    -= b_low;
    b_low
    = 0;
    while(b_low <= b_high)
    {
    b_mid
    = (b_low+b_high)>>1;
    for(low = (map[0][0]-b_mid)>0?(map[0][0]-b_mid):0;
    low
    <= map[0][0]; ++low)
    {
    CLR(visit,
    0);
    high
    = low + b_mid;
    if(dfs(0,0))
    {
    ans
    = b_mid;
    break;
    }
    }
    if(low <= map[0][0])
    b_high
    = b_mid - 1;
    else
    b_low
    = b_mid + 1;
    }
    printf(
    "Scenario #%d:\n",tt);
    OUT(ans);
    printf(
    "\n");
    tt
    ++;
    return 0;
    }
    int main()
    {
    int t;
    tt
    = 1;
    IN(t);
    while(t--)
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    一文读懂比特币的软分叉
    区块链的七阶段位,你属于哪一段?
    总价值超26.7亿美元的5个最富有比特币地址汇总
    智能合约的沙箱机制是什么?
    区块链的核心技术是什么?
    区块链和比特币常见的七大误区
    矿机论斤卖?夸大其词
    比特币跌破5000美元的三大影响因素
    微软Azure区块链开发工具包三大功能详解
    各大自媒体平台的收益情况汇总
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1717457.html
Copyright © 2011-2022 走看看