标签:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=127062
题意:已知两个数m,n,通过A按钮,数字可以乘2,B按钮数字减1,通过两个按钮操作,求使得m转变成n的最小步数,其中当数字不是正数的时候,机器停止运转。
解题思路:首先有两种状态,一种是乘一种是减。很明显这道题用的是搜索而且是bfs。需要考虑在运行搜索过程中运算的最大值和最小值,很明显不断的乘2会使数字越界。所以最好的办法就是转变为由n到m,则最大值就是边界的二倍。同时需要记录访问过的点,因为访问过的点,下一次不应该被再一次访问,这样会超时。
总结:为啥我交了13遍才过,第一,没有考虑搜索过程中数字乘过之后会越界,第二在搜索的时候可能会有重复,就是重复访问同一个数字。边界条件,就是数字不能小于零,不能重复访问。
#include<iostream> #include<cstring> #include<queue> #include<stdio.h> using namespace std; int n, m,s,t,sum; struct point{ int ans,x; }; int vis[40005]; void bfs(){ queue<point> que; point start; start.ans = 0; start.x=n; vis[n]=1; que.push(start); while(!que.empty()){ point u=que.front(); que.pop(); for(int i=0;i<2;i++){ int x; if(i==0) x=u.x/2; else x=u.x+1; int y=u.ans+1; if(i==0&&u.x%2!=0) continue; if(vis[x]==1)continue; vis[x]=1; if(x==m) { sum=y; return; } point next; next.x=x; next.ans=y; que.push(next); } } } int main(){ while(scanf("%d%d", &m, &n)!=EOF ) { memset(vis,0,sizeof(vis)); sum=0; if(m==n) sum=0; else bfs(); printf("%d\n",sum); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Yvettey-me/p/4693293.html