1. 题目源地址:http://acm.tju.edu.cn/toj/showp.php?pid=3071
2. 题目大意:给出K和P两个数,对K进行乘2或者除2(当K为偶数时),或者加1操作。输出使K变成P的最少操作步数。
3. 源代码:
以下给出两种代码,一种使用队列,另外一种使用数组实现队列。两种代码本质上是相同的,只不过用了不同的方式实现队列功能。
本题和POJ上的3278:Catch The Cow很相似,给出该题的解题报告链接:http://blog.csdn.net/u012856866/article/details/38872643
(1)使用队列
#include<iostream>
#include<queue>
#include<memory.h>
#define MAX 100010
using namespace std;
int visited[MAX];
int K,P,ans;
struct node
{
int x;
int step;
}start,current,next;
int BFS()
{
queue<node> Q;
int i;
start.x=K;
start.step=0;
Q.push(start);
visited[start.x]=1;
while(!Q.empty())
{
current=Q.front();
Q.pop();
for(i=0;i<3;i++)
{
if(i==0) next.x=current.x*2;
else if(i==1)
{
if(current.x%2==0)
next.x=current.x/2;
}
else if(i==2) next.x=current.x+1;
next.step=current.step+1;
if(next.x==P) return next.step;
if(next.x>0 && next.x<100000 && !visited[next.x])
{
Q.push(next);
visited[next.x]=1;
}
}
}
return 0;
}
int main()
{
int caseNum;
cin>>caseNum;
while(caseNum--)
{
memset(visited,0,sizeof(visited));
cin>>K>>P;
ans=BFS();
if(ans) cout<<ans<<endl;
else cout<<-1<<endl;
}
return 0;
}
(2)使用数组实现队列功能
//TJU Exam 2008--3071:Number Game
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define max 100000
using namespace std;
int visited[max];
struct Point
{
int x;
int step;
}queue[max];
int BFS(int s, int e)
{
int i,j,top,tx;
queue[0].x=s;
queue[0].step = 0;
visited[s] = 1;
top = 1;
for(i=0;i<top;i++)
{
if(queue[i].x == e)// 当得到满足条件的数时,返回 step
return queue[i].step;
tx = queue[i].x*2; // 1. Multiply current number by 2
if(tx<max && !visited[tx])
{
queue[top].x = tx;
queue[top].step = queue[i].step+1;
visited[tx] = 1;
top++;
}
if(queue[i].x%2 ==0) // 2. Divide current number by 2, if current number is even.
{
tx = queue[i].x/2;
if(tx>0 && !visited[tx])
{
queue[top].x = tx;
queue[top].step = queue[i].step +1;
visited[tx] = 1;
top++;
}
}
tx = queue[i].x +1; // 3. Increase current number by 1
if(tx<max &&!visited[tx])
{
queue[top].x = tx;
queue[top].step = queue[i].step +1;
visited[tx]=1;
top++;
}
}
return -1;
}
int main()
{
int start,end,cas;
cin>>cas;
while(cas--)
{
cin>>start>>end;
memset(visited,0,sizeof(visited));
cout<<BFS(start,end)<<endl;
}
return 0;
}
(数组实现队列简化版):
#include<iostream>
#include<memory.h>
using namespace std;
int visited[100010];
struct node
{
int x;
int step;
}queue[100010];
int BFS()
{
int i,j,top,tx;
queue[0].x=K;
queue[0].step=0;
visited[queue[0].x]=1;
top=1;
for(i=0;i<top;i++)
{
if(queue[i].x==P)
return queue[i].step;
for(j=0;j<3;j++)
{
if(j==0) tx=queue[i].x*2; //乘2
else if(j==1) //除2
{
if(queue[i].x%2==0)
tx=queue[i].x/2;
}
else if(j==2) tx=queue[i].x+1; //加1
//将tx如队列
if(tx>0 && tx<100000 && !visited[tx])
{
queue[top].x=tx;
queue[top].step=queue[i].step+1;
visited[tx]=1;
top++;
}
}
}
return 0;
}
int main()
{
int caseNum;
cin>>caseNum;
while(caseNum--)
{
memset(visited,0,sizeof(visited));
cin>>K>>P;
ans=BFS();
if(ans) cout<<ans<<endl;
else cout<<-1<<endl;
}
return 0;
}