I - Interesting Calculator-Team Contest 4th(BFS-优先队列优化)

 

  •   题意:给你两个数x,y。由x每次可以经过一系列操作变换,每个变换都有一定的费用,求x变换到y的最小费用下最小步数。
  •   思路:类似最短路的思想,当时只想到每个点有30个方向可以走,于是直接广搜,但不是TLE就是MLE,后来比完赛看题解才知道要用优先队列。最小费用优先,然后最小步数优先。每一步都是前一步到达的,但一个点可以由多个点到达,这时我们肯定要取最优的那一步嘛。如果我们不用标记,那么就存在重复走的过程,这样TLE和MLE是很合理的,但标记的话如果不用优先队列就可能导致这一步并不是由最优路线得到的,而我们直接就将其堵塞了。。。这个题关键就是这么最短路的思想,而且我们保证第一次到达这个y点一定是最优解,直接return,否则还是会超时的。
  • 优先队列 重构结构体。
  • I - Interesting Calculator

     UVA - 12664 
  • #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    int nxt[5][15],x,y,ans,cnt;
    int vis[100005];
    struct node
    {
        int num,cost,step;
        friend bool operator >(node a,node b)
        {
            if(a.cost>b.cost)
                return true;
            else if(a.cost==b.cost&&a.step>b.step)
                return true;
            else
                return false;
        }
    } temp1,temp2;
    void bfs()
    {
        memset(vis,inf,sizeof(vis));
        priority_queue<node,vector<node>,greater<node> >q;
        temp1.cost=0;
        temp1.num=x;
        temp1.step=0;
        q.push(temp1);
        vis[x]=0;
        while(!q.empty())
        {
            temp1.num=q.top().num;
            temp1.cost=q.top().cost;
            temp1.step=q.top().step;
            q.pop();
            if(temp1.num==y)
            {
                ans=temp1.cost;
                cnt=temp1.step;
                return ;
            }
            else
            {
                for(int i=2; i>=0; i--)
                    for(int j=9; j>=0; j--)
                    {
                        if(i==0)
                        {
                            temp2.cost=temp1.cost+nxt[i][j];
                            temp2.num=temp1.num*10+j;
                            temp2.step=temp1.step+1;
                        }
                        if(i==1)
                        {
                            temp2.cost=temp1.cost+nxt[i][j];
                            temp2.num=temp1.num+j;
                            temp2.step=temp1.step+1;
                        }
                        if(i==2)
                        {
                            temp2.cost=temp1.cost+nxt[i][j];
                            temp2.num=temp1.num*j;
                            temp2.step=temp1.step+1;
                        }
                        if(temp2.num>y)
                            continue;
                        else if(temp2.cost<vis[temp2.num])
                        {
                            vis[temp2.num]=temp2.cost;
                            q.push(temp2);
                        }
                    }
            }
        }
    }
    int main()
    {
        int aaaaa=1;
        while(cin>>x>>y)
        {
            memset(nxt,0,sizeof(nxt));
            ans=inf;
            for(int i=0; i<3; i++)
                for(int j=0; j<10; j++)
                    cin>>nxt[i][j];
            bfs();
            cout<<"Case "<<aaaaa++<<": "<<ans<<" "<<cnt<<endl;
        }
        return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值