请教一道C语言题

周靖峰 2010-06-10 09:25:40
题目如下

抓住奶牛!★★★★

Time Limit:1000MS Memory Limit:65536K
Total Submit:45 Accepted:12

Description

不得了,xiaoC的农场里跑出来了一只奶牛,这可是让xiaoC很是揪心啊,于是xiaoC立刻放下了手头的工作,想疯狂的奶牛奋力追去,但说来也怪,xiaoC的走法还真有一点特殊,他每一步有两种走法:

步行:xiaoC可以从任何X位置,一步走到X-1或X+1位置
跳跃:xiaoC可以从任意X位置,一步跳跃到2*X的位置

现在我们假设奶牛并没有意识到xiaoC的追来,还在原地傻傻地站着,请你来帮xiaoC计算一下,他需要多少步,才能把奶牛逮住!!!


Input

每个测试实例为一行,包含两个数据,N和K,N表示xiaoC现在的位置,K表示奶牛的位置,0 ≤ N,K ≤ 100,000

Output

输出xiaoC能逮住奶牛的最少步数,每个测试实例输出一行

Sample Input


5 17

Sample Output


4

Hint

在这个实例中最快的路径为5-10-9-18-17,共四步

Source

xiaoC


我的第一个想法是倒着来,但是不行
然后我想正着来,以5和35为例,5在4-8之间,取n1=2。35在32-64之间,取n2=5。首先判断5*2^(n2-n1)-35是否大于2^(n2-n1),如果大于则5-1, 如此下去。但也不行。

所以请教大牛们,这道题有什么其他的思路。
...全文
306 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2010-06-12
  • 打赏
  • 举报
回复
lz,请参考下面链接:
http://blog.csdn.net/china8848/archive/2008/03/06/2155305.aspx
http://hi.baidu.com/sunkehappy/blog/item/d899e1d359f9820c3bf3cf41.html/cmtid/c2e4d824c50c1e3ec9955975

http://www.slyar.com/blog/poj-3278-cpp.html
http://blog.sina.com.cn/s/blog_59e67e2c0100aan7.html
周靖峰 2010-06-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 liao05050075 的回复:]
是数据结构里的内容。你可以找找相关的书看一下先。

这个是个USACO的老题目了,poj上面有。很久之前我做过。下面是原题和我当时的代码(是C++的),你可参考一下。
Catch That Cow
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 16224 Accepted: 4975

Description
……
[/Quote]

6楼的算法我有点看不懂,连4个头文件我也只认识两个,而且STL也不会用,所以我只好自己再想办法
根据楼上的想法,我决定还是用man+1,man-1,man*2方法做,不过这一回我把得到的数放入队列中进行循环
比如说5,17这组,首先将5入队,然后5出队,然后4!=17入队,6!=17入队,10!=17入队,4出队……
直到找到17为止结束,另外我定义的元素不是单纯的元素,我是将数和步数放在一个结构体中
比如5的步数是0, 4、6、10的步数是1……
我感觉我的算法应该是正确的啊,为什么还是通不过呢??

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0

typedef struct //将数字和步数放一起
{
int num;
int step;
}ElemType;

typedef struct QueueNode //定义队列结点
{
ElemType data;
struct QueueNode *next;
}QueueNode;

typedef struct //定义队列
{
QueueNode *front;
QueueNode *rear;
}Queue;

int InitQueue(Queue *Q) //初始化队列
{
Q->front = Q->rear = (QueueNode *)malloc(sizeof(QueueNode));
if (Q->front == NULL)
return FALSE;
Q->front->next = NULL;
return TRUE;
}

int EnterQueue(Queue *Q, ElemType e) //入队
{
QueueNode *t;
t = (QueueNode *)malloc(sizeof(QueueNode));
if (t == NULL)
return FALSE;
t->data = e;
t->next = NULL;
Q->rear->next = t;
Q->rear = t;
return TRUE;
}

int DeleteQueue(Queue *Q, ElemType *e) //出队
{
QueueNode *t;
t = Q->front->next;
if (t == NULL)
return FALSE;
(*e) = t->data;
if (t == Q->rear)
{
Q->rear = Q->front;
Q->front->next = NULL;
}
else
Q->front->next = t->next;
free(t);
return TRUE;
}

int main()
{
int man, cow;
int n;
Queue Q;
ElemType e;
ElemType t;

scanf("%d%d", &man, &cow);
if (man == cow)
n = 0;
else if (man > cow)
n = man - cow;
else
{
e.num = man;
e.step = 0;
InitQueue(&Q);
EnterQueue(&Q, e);
while (1)
{
DeleteQueue(&Q, &e);
t.num = e.num - 1; //对应man-1这种情况
t.step = e.step + 1;
if (t.num == cow)
{
e = t;
break;
}
else if (t.num < 0) //如果小于0就没有必要入队
goto s;
else
EnterQueue(&Q, t);

if (e.num > cow) //如果当前man的坐标大于cow的坐标,没有必要再往上加
continue;

s: t.num = e.num + 1; //对应man+1这种情况
t.step = e.step + 1;
if (t.num == cow)
{
e = t;
break;
}
else
EnterQueue(&Q, t);

t.num = e.num * 2; //对应man*2这种情况
t.step = e.step + 1;
if (t.num == cow)
{
e = t;
break;
}
else
EnterQueue(&Q, t);
}
n = e.step;
}
printf("%d", n);
return 0;
}
aperson111 2010-06-11
  • 打赏
  • 举报
回复
不会,来学习
ForestDB 2010-06-11
  • 打赏
  • 举报
回复
帮顶。
JJ___JJ 2010-06-11
  • 打赏
  • 举报
回复
顶起,接分…………

aperson111 2010-06-11
  • 打赏
  • 举报
回复
发现自己错了
希望有强人来对这个题目做个详细解释,让大家都能学习
[Quote=引用 14 楼 aperson111 的回复:]
思考了下,不知道我的理解和算法对不对
至于楼上的动态规则等算法,完全没有理解和这个题的关联,唉,还是基础差

C/C++ code

#include <iostream>
#include <queue>
using namespace std;

queue<int> calcu(int N, int K)
{
int tempN = N;
queue<……
[/Quote]
aperson111 2010-06-11
  • 打赏
  • 举报
回复
思考了下,不知道我的理解和算法对不对
至于楼上的动态规则等算法,完全没有理解和这个题的关联,唉,还是基础差

#include <iostream>
#include <queue>
using namespace std;

queue<int> calcu(int N, int K)
{
int tempN = N;
queue<int> qN;
qN.push(tempN);
while(tempN != K)
{
if(tempN*2 > (K+1))
{
tempN--;
qN.push(tempN);
}
else
{
tempN*=2;
qN.push(tempN);
}
}
return qN;
}
int main()
{
int N;
int K;
cin>>N;
cin>>K;
while(N>0 && K>0 && N<10000 && K < 10000)
{
queue<int> qN = calcu(N,K);
int size = qN.size();
for(int i = 0; i < size; i++)
{
cout<<qN.front()<<" ";
qN.pop();
}
cout<<endl;
cin>>N;
cin>>K;
}
return 0;
}
qq120848369 2010-06-10
  • 打赏
  • 举报
回复
总得有个界,晚上想想
qq120848369 2010-06-10
  • 打赏
  • 举报
回复
用那位大哥的方法,倒着来.
周靖峰 2010-06-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qq120848369 的回复:]
动态规划的,
step[i]=min{step[i-1],step[i+1],step[2*i]}+1; i<k
step[i]=0; i=k;
step[i]=i-k; i>k;

i>k的不用存储,直接拿来计算就可以,那么就需要100000的空间. 慢慢算把..
[/Quote]

貌似用递归会输不出结果
#include <stdio.h>

int function(int man, int cow)
{
int a, b, c;
if (man == cow)
return 0;
if (man > cow)
return (man - cow);
a = function(man - 1, cow) + 1;
b = function(man + 1, cow) + 1;
c = function(man * 2, cow) + 1;
a = a < b ? a : b;
a = a < c ? a : c;
return a;
}

int main()
{
int man, cow;
int n;

scanf("%d%d", &man, &cow);
n = function(man, cow);
printf("%d", n);
return 0;
}
qq120848369 2010-06-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 whg01 的回复:]

动态规划。设f(i)表示跳到第i格所需要的最少步数,i>=1:
当i=N时,f(i)=0;
如果i为偶数:
f(i)=min(f(i/2), f(i-1), f(i+1))+1;
如果i为奇数:
f(i)=min(f(i-1), f(i+1))+1;
[/Quote]

这个应该可以了,用递归实现,用备忘录看看.
ImJaden 2010-06-10
  • 打赏
  • 举报
回复
算法题呀。呵呵学习
liao05050075 2010-06-10
  • 打赏
  • 举报
回复
是数据结构里的内容。你可以找找相关的书看一下先。

这个是个USACO的老题目了,poj上面有。很久之前我做过。下面是原题和我当时的代码(是C++的),你可参考一下。
Catch That Cow
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 16224 Accepted: 4975

Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input
Line 1: Two space-separated integers: N and K

Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

Source
USACO 2007 Open Silver

#include<iostream>
#include<algorithm>
#include<queue>
#include<set>

using namespace std;

bool s[200001];
int bfs(int n,int k)
{
if(k<=n) return n-k;

int layer=0,i;
int size=1;
queue<int>q;
memset(s,0,sizeof s);
q.push(n);
s[n]=1;
while(1)
{
layer++;
while(size--)
{
n=q.front();
q.pop();
int a[3]={n+1,n-1,n*2};
for(i=0;i<3;i++)
{
if(a[i]==k) goto out;
if(a[i]>0&&a[i]<=200000&&!s[a[i]])
{
q.push(a[i]);
s[a[i]]=1;
}
}
}
size=q.size();
}
out: return layer;
}

int main()
{
int k;
int n;
while(cin>>n>>k)
{
cout<<bfs(n,k)<<endl;
}
return 0;
}
whg01 2010-06-10
  • 打赏
  • 举报
回复
动态规划。设f(i)表示跳到第i格所需要的最少步数,i>=1:
当i=N时,f(i)=0;
如果i为偶数:
f(i)=min(f(i/2), f(i-1), f(i+1))+1;
如果i为奇数:
f(i)=min(f(i-1), f(i+1))+1;
qq120848369 2010-06-10
  • 打赏
  • 举报
回复
动态规划有点问题,不能这样,我再想想别的办法.
周靖峰 2010-06-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 liao05050075 的回复:]
一个简单的BFS广度搜索
[/Quote]
没学过,请教一下什么是BFS广度搜索,是数据结构里的内容吗?
qq120848369 2010-06-10
  • 打赏
  • 举报
回复
动态规划的,
step[i]=min{step[i-1],step[i+1],step[2*i]}+1; i<k
step[i]=0; i=k;
step[i]=i-k; i>k;

i>k的不用存储,直接拿来计算就可以,那么就需要100000的空间. 慢慢算把..
liao05050075 2010-06-10
  • 打赏
  • 举报
回复
一个简单的BFS广度搜索

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧