CSUOJ 1336 Interesting Calculator(BFS+优先队列)

来源:互联网 发布:vnr更新网络 编辑:程序博客网 时间:2024/06/02 02:12

题目大意:输入两个数,总共有三大种可能到达的状态:1.第一个数后面添加一位数(0,1,2,3...9);2.第一个数+一个数(0,1,2,3...9);3.第一个数*一个数(0,1,2,3...9);

下面3行10列分别对应到达每种状态的花费,求从第一个数变到第二个数的最小花费和最小变换次数。

#include<stdio.h>#include<string.h>#include<queue>using namespace std;int m,n;int a[5][20];bool vis[100005];int count1,count2;struct node{int x;int cost;int step;friend bool operator<(const node a,node b){  //优先选择花费小的,若花费相同,则优先选择变换次数少的if(a.cost!=b.cost)return a.cost>b.cost;elsereturn a.step>b.step;}}cur,next;int judge(int k){int count=0;while(k){count++;k/=10;}return count;}void bfs(){memset(vis,false,sizeof(vis));priority_queue<node> q;cur.x=m;cur.cost=0;cur.step=0;q.push(cur);while(!q.empty()){cur=q.top();q.pop();if(vis[cur.x])//  此题的关键continue;vis[cur.x]=true;//  此题的关键    利用优先队列  标记当前这个数 费用最小的状态  过滤那些 费用大于它的同一状态if(cur.x==n){printf("%d %d\n",cur.cost,cur.step);return ;}for(int i=0;i<3;i++){for(int j=0;j<10;j++){count2=judge(cur.x);if(i==0&&count2<count1){next.x=cur.x*10+j;}else if(i==1){next.x=cur.x+j;}else{next.x=cur.x*j;}if(next.x>n)continue;if(!vis[next.x]){next.cost=cur.cost+a[i][j];next.step=cur.step+1;q.push(next);}}}}}int main(){int t=0;while(scanf("%d%d",&m,&n)!=EOF){t++;for(int i=0;i<3;i++){for(int j=0;j<10;j++){scanf("%d",&a[i][j]);}}count1=judge(n);printf("Case %d: ",t);bfs();}return 0;}


0 0