一个问题

zengkun100 2007-01-09 11:27:45
如果n为偶数,则将它除以2,
如果n为奇数,则将它加1或者减1。
问对于一个给定的n,怎样才能用最少的步骤将它变到1。
例如:
n= 61
n-- 60
n/2 30
n/2 15
n++ 16
n/2 8
n/2 4
n/2 2
n/2 1


我的想法是这样的:
当n为偶数时,没得选择,除以2就好。所以关键是看对奇数时怎么处理。
当n为奇数时,如果为1,就结束了,如果不为1,那肯定可以表示成下面得等式:
n=m*2+1
此时选择对n是加1还是减1呢?
如果上式中的m是偶数的话,那n减1,因为m可以继续除以2。如果m是奇数的话,n加1,再除以2之后得到m+1,m+1是偶数可以继续除以2。

我觉得基本上就是“贪心”的思想。
...全文
398 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Evilblood 2007-01-18
  • 打赏
  • 举报
回复
这个算法应该是对的 时间复杂度应该是lg(n)

还有一种比较低效的算法 就是建立一张图[0,n][0,n] 把[i,i+1] [i,i-1] [i,i*2]连起来 然后求最短路
Evilblood 2007-01-18
  • 打赏
  • 举报
回复
伪代码

str=N转化为2进制数的字符串;
carry=1;
temp=0;
flag[]=0; //flag中记录了某步应该+1或-1
for (i=0;i<=len(str);i++)
{
if (str[i]=='1')
{
if (temp==0) low=i;
temp++;
}
else
temp=0;
if ((temp>2)&&(str[i+1]=='0'))
{
flag[low]=1;
if (i!=len(str))
{
flag[i]=-1;
carry=0;
}
}
elseif (i!=n)
{
flag[i]=-1;
if (temp==2)
flag[i-1]=-1;
}
}

for (i=len(str)-carry;i>=0;i--)
{
if (flag[i]==0)
cout<<"/2";
elseif (flag[i]==1)
{
cout<<"+1";
cout<<"/2";
}
else
{
cout<<"-1";
cout<<"/2";
}
}
HewpKanXue 2007-01-14
  • 打赏
  • 举报
回复
补充,如果=3 则作特例处理。
HewpKanXue 2007-01-14
  • 打赏
  • 举报
回复
粗粗地想了一下,得到一个奇数数后,先做模4运算,如果=1则-1,如果=3则+1,好像就可以了,楼下继续想.
zengkun100 2007-01-14
  • 打赏
  • 举报
回复
zhaoxinmao
你算算63是加1之后更快还是减1之后更快?
zhaoxinmao 2007-01-13
  • 打赏
  • 举报
回复
应该是-1吧。。
hxDreamer 2007-01-13
  • 打赏
  • 举报
回复
ls对不起 算法的知识我实在不会啊,毕竟还是新手。
我是觉得对于63这样的数+1之后可以一连串的被2整除了,是不是就少了很多步?
zengkun100 2007-01-12
  • 打赏
  • 举报
回复
hxDreamer
那请问该怎么想呢?
我觉得这个问题很符合贪心算法的要求。
hxDreamer 2007-01-11
  • 打赏
  • 举报
回复
我感觉:+1还是-1的问题,不是应该考虑+/-1之后的数能被2整除的次数。比如,63+1=64,64/2=32,32/2=16,16/2=8。。。而63-1=62,62/2=31。。。这样行么。。。

新手就这么想。。
zengkun100 2007-01-11
  • 打赏
  • 举报
回复
这是Trilogy公司的笔试题目。
taodm说向2^n靠拢,2^n是指数级增长,两个值之间相差很大,2^10=1024,2^11=2048。
现在给你一个1537,显然它更靠近2048,你说1537是加1还是减1呢?加1就更靠近2048了,但是减1才是正确的做法。

Vibot说的是啊!我犯傻了:)
msccao 2007-01-10
  • 打赏
  • 举报
回复
将你们的思路综合一下,
OOPhaisky 2007-01-10
  • 打赏
  • 举报
回复
同意taodm的说法,尽量向2^n靠拢
Vibot 2007-01-10
  • 打赏
  • 举报
回复
n=3=1*2+1时,按你说的应该是+1,则需要除两次,而-1的话,只需要除一次... :)
zwr1980 2007-01-10
  • 打赏
  • 举报
回复
应该向2的n次方靠,再取余,能用最少的步骤达到目的
taodm 2007-01-10
  • 打赏
  • 举报
回复
也许,向2的n次方靠是个思路。
暂时不细想了。

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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