#POJ2331#Water pipe(IDA*_搜索)

原创 2017年10月06日 21:32:39

Water pipe
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 2508   Accepted: 715

Description

The Eastowner city is perpetually haunted with water supply shortages, so in order to remedy this problem a new water-pipe has been built. Builders started the pipe from both ends simultaneously, and after some hard work both halves were connected. Well, almost. First half of pipe ended at a point (x1, y1), and the second half -- at (x2, y2). Unfortunately only few pipe segments of different length were left. Moreover, due to the peculiarities of local technology the pipes can only be put in either north-south or east-west direction, and be connected to form a straight line or 90 degree turn. You program must, given L1, L2, ... Lk -- lengths of pipe segments available and C1, C2, ... Ck -- number of segments of each length, construct a water pipe connecting given points, or declare that it is impossible. Program must output the minimum required number of segments. 

Constraints 
1 <= k <= 4, 1 <= xi, yi, Li <= 1000, 1 <= Ci <= 10

Input

Input contains integers x1 y1 x2 y2 k followed by 2k integers L1 L2 ... Lk C1 C2 ... Ck

Output

Output must contain a single integer -- the number of required segments, or −1 if the connection is impossible.

Sample Input

20 10 60 50 2 70 30 2 2

Sample Output

4

题意:

给出K种长度的水管,并告诉每种长度有多少根,要求用这些水管从(x1,y1)一直铺到(x2,y2),最少使用多少根水管,水管可以交叉。

注意水管铺的范围坐标在0 ~ 1000


剪枝很重要,H值得设置如下:

假设现在只考虑一个坐标,那么BFS计算出可能到达的所有单个坐标的最少管道数量,

而对于当前的点x,y,它到达终点的管道数量,一定能保证大于等于Bfs单座标数+当前数,


Code:

Status Accepted
Time 641ms
Memory 744kB
Length 2111
Lang G++
Submitted
Shared
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int Max = 6;

bool flg;
int K, lim, sum;
int x1, y1, x2, y2;
int L[Max], C[Max], H1[1005], H2[1005];
int dd[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

void getint(int & num){
    char c; int flg = 1;    num = 0;
    while((c = getchar()) < '0' || c > '9') if(c == '-')    flg = -1;
    while(c >= '0' && c <= '9'){    num = num * 10 + c - 48;    c = getchar(); }
    num *= flg;
}

int Bfs_H(int * H, int s){
    queue<int>Q;
    H[s] = 0;
    Q.push(s);
    while(! Q.empty()){
        int tmp = Q.front();    Q.pop();
        for(int i = 1; i <= K; ++ i){
            int x = tmp - L[i];
            if(x > 0 && H[x] == -1)
                H[x] = H[tmp] + 1,
                Q.push(x);
            x += (L[i] << 1);
            if(x <= 1000 && H[x] == -1)
                H[x] = H[tmp] + 1,
                Q.push(x);
        }
    }
}

void Dfs(int x, int y, int now, int *state){
    if(now > lim)   return ;
    if(x == x2 && y == y2){flg = 1; return ;}
    if(now + H1[x] > lim || now + H2[y] > lim) return ;
    int newstate[Max];
    memcpy(newstate, state, sizeof newstate);
    for(int i = 1; i <= K; ++ i)    if(newstate[i]){
        -- newstate[i];
        for(int j = 0; j < 4; ++ j){
            int xx = x + L[i] * dd[j][0];
            int yy = y + L[i] * dd[j][1];
            if(xx >= 0 && yy >= 0 && xx <= 1000 && yy <= 1000)
                Dfs(xx, yy, now + 1, newstate);
            if(flg) return ;
        }
        ++ newstate[i];
    }
}

int main(){
    getint(x1), getint(y1), getint(x2), getint(y2);
    getint(K);
    for(int i = 1; i <= K; ++ i)    getint(L[i]);
    for(int i = 1; i <= K; ++ i)    getint(C[i]), sum += C[i];
    if(x1 == x2 && y1 == y2){puts("0"); return 0;}
    memset(H1, -1, sizeof H1 );
    memset(H2, -1, sizeof H2 );
    Bfs_H(H1, x2);
    Bfs_H(H2, y2);
    for(lim = 1; lim <= sum; ++ lim){
        Dfs(x1, y1, 0, C);
        if(flg) break;
    }
    if(flg) printf("%d\n", lim);
    else puts("-1");
    return 0;
}









IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数

打开IDA一般都是去搜索函数,可以说函数是IDA工程的基本单位吧,数据结构什么的都是为函数服务而已。函数列表在界面左侧的Functions Window: 可以看到,UIKit有27789个函数呢...
  • hursing
  • hursing
  • 2013-05-14 18:40:23
  • 10551

使用IDA逆向定位病毒特征码

对于木马技术爱好者来说,会做免杀是必然的一项技术,在自己编写的马被杀的情况下,结合源代码定位出被杀的函数是免杀中重要的一项技能。 杀毒软件在定位特征码的时候,有时定位的导入导出函数,这种情况相对好找,...
  • chinafe
  • chinafe
  • 2010-03-16 09:06:00
  • 3420

IDA PRO逆向调试记录与常用快捷键

使用IDA Pro定位关键代码的方法: 1、搜索特征字符串。具体操作为:      ①快捷键Ctrl+S,打开搜索类型选择对话框-->双击Strings,跳到字符串段-->菜单项“Search-->...
  • u010725842
  • u010725842
  • 2016-02-23 14:50:06
  • 10582

16.IDA-列出函数中存在的全部call

有时待分析的函数反汇编太长,需要确认此函数调用了哪些call 选择View▶Open Subviews▶Function Calls窗口 窗口的上半部分列出了所有调用当前函数(由打开窗口时光标所...
  • hgy413
  • hgy413
  • 2016-01-28 10:30:25
  • 2075

搜索算法:IDA*算法

搜索算法:IDA*算法 分类: 算法与数据结构2010-09-01 22:30 2922人阅读 评论(2) 收藏 举报 算法扩展structc游戏up 今天学习了IDA*算法...
  • pi9nc
  • pi9nc
  • 2013-09-23 20:16:26
  • 3410

ida 中hexview快速跳转到内存地址

转:http://bbs.pediy.com/showthread.php?p=1331140#post1331140 问: 比如图上选中的 0x61EFE608,怎么能快速跳转到该地址。 ...
  • zhangmiaoping23
  • zhangmiaoping23
  • 2015-09-09 13:11:38
  • 3105

利用ida对程序的静态链接库进行处理

用IDA进行反汇编时最怕遇到的就是跟踪到了程序静态链接的库函数中,看得一头雾水不说,还浪费了大量的时间。其实如果有符号表的话,看看函数名就知道大概功能了,再看看参数就可以pass了。本文以meterp...
  • liujiayu2
  • liujiayu2
  • 2016-05-30 11:40:14
  • 1216

使用IDA的跟踪功能

一个小bug程序 这个小程序只是简单的计算了一下一组数据(1,2,3,4,5)的平均值。这组数据被保存在两个数组里,一个是8bit的数值,一个是32bit数值表示。 #include char...
  • eqera
  • eqera
  • 2012-11-29 11:31:36
  • 13061

IDA*,迭代加深搜索(编辑书稿,uva 11212)

复习一下,好处多多。 一开始用vector,真是慢死了,直接超时。 后来改成int就过了。 迭代加深搜索从0开始搜。 如何对int进行剪切想了一段时间。 代码 #include...
  • xl2015190026
  • xl2015190026
  • 2016-08-07 01:38:31
  • 226

【启发式搜索】A*与IDA*学习笔记

搞了这么久发现自己到现在还不会启发式搜索ヾ(。`Д´。)所以今天正好趁着搜索练习题的风去搞了启发式搜索 A*搜索算法,俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法...
  • CreationAugust
  • CreationAugust
  • 2014-12-14 21:48:24
  • 1598
收藏助手
不良信息举报
您举报文章:#POJ2331#Water pipe(IDA*_搜索)
举报原因:
原因补充:

(最多只允许输入30个字)