zoukankan      html  css  js  c++  java
  • poj2331 (IDA*)

    题意:给你k种管道,然后是每种的长度,每种的数量,求(x1,y1)到(x2,y2)所用管道的最少数量

    思路:

    最开始考虑的是直接bfs,但是没有成功。

    然后发现可以先找x轴x1 到 x2 ,再找y轴y1 到 y2。两个的和便是最终答案。

    先用bfs处理出两条轴上的估计函数(即每个地方到x2或y2的距离),然后枚举深度搜索。


    Orz;

    1.最开始思路的方向就错了,没想到可以x,y轴分开来考虑- -,果然脑子转不过来

    2.而且最后忘了判断是否有答案,贡献了个TL


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <algorithm>
    typedef long long ll;
    using namespace std;
    
    int len[5];
    int num[5];
    int have1[1005];
    int have2[1005];
    int x1,x2,y2,y1,k;
    
    
    void bfs(int *a,int to)    //估价函数,到to的最小步数
    {
        queue<int >q;
        q.push(to);
        a[to] = 0;
        while(!q.empty())
        {
            int cur = q.front();
            q.pop();
    
            for(int i = 0; i < k; i++)
            {
                if(cur-len[i] > 0 && a[cur-len[i]] == -1)
                {
                    a[cur-len[i]] = a[cur] + 1;
                    q.push(cur-len[i]);
                }
    
                if(cur+len[i]<= 1000 &&  a[cur+len[i]] == -1)
                {
                    a[cur+len[i]] = a[cur]+1;
                    q.push(cur+len[i]);
                }
            }
        }
    }
    
    bool IDA(int cur,int now,int ci,int flag)
    {
        if(!flag)
        {
            if(cur + have1[now] > ci)
                return false;
            if(now == x2)              //当x轴已经达到目标点x2,去搜索y轴
            {
                if(IDA(0,y1,ci-cur,1))
                    return true;
            }
        }
    
        if(flag)
        {
            if(cur+have2[now] > ci)
                return false;
            if(now == y2)               //y轴到达y2点
                return true;
        }
    
        for(int i = 0; i < k; i++)
        {
            if(num[i] > 0)    //还能添加i
            {
                num[i]--;
                if(flag == 0)
                {
                    if(now + len[i] <= 1000) if(IDA(cur+1,now+len[i],ci,flag)) return true;
                    if(now - len[i] > 0) if(IDA(cur+1,now-len[i],ci,flag)) return true;
                }
                else
                {
                    if(now + len[i] <= 1000) if(IDA(cur+1,now+len[i],ci,flag)) return true;
                    if(now - len[i] > 0) if(IDA(cur+1,now-len[i],ci,flag)) return true;
                }
                num[i]++;
            }
        }
        return false;
    }
    
    int main()
    {
        while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2) != EOF)
        {
            int tmax = 0,ans;
            scanf("%d",&k);
            for(int i = 0; i < k; i++)
                scanf("%d",len+i);
    
            for(int i = 0; i < k; i++)
            {
                scanf("%d",num+i);
                tmax += num[i];
            }
            if(x1 == x2 && y1 == y2)
            {
                printf("0
    ");
                continue;
            }
    
            memset(have1,-1,sizeof(have1));
            memset(have2,-1,sizeof(have2));
            bfs(have1,x2);
            bfs(have2,y2);
            for(int i = 0;; i++)
            {
                if(IDA(0,x1,i,0))
                {
                    ans = i;
                    break;
                }
                if(i > tmax){         //找不到答案
                    ans = 10000;
                    break;
                }
            }
            if(ans <= tmax)
                printf("%d
    ",ans);
            else
                printf("-1
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    学习shell script
    ubuntu11.10安装出现/cdrom问题以及不能格式成ext问题
    正则表达式
    认识与学习bash(2)
    UNIX网络编程 一个简单的时间获取客户程序
    HDU4522
    恢复引导
    认识与学习bash(1)
    文件格式化处理
    C++解析csv文件
  • 原文地址:https://www.cnblogs.com/Przz/p/5409704.html
Copyright © 2011-2022 走看看