搜狐2018技术岗笔试第二题,移动最少次数到达坐标

刚刚昨晚搜狐技术岗笔试,第二道编程是数学题呀=。=好可惜到最后才想起来



用 i 步走到 target 数值,其实就是用 1,2,..,i 这 i 个数字,每个数字前面插入 + 号或 - 号,运算得到 target 。
1 到 i 到和是 (1+i)i/2 ,假设已经确定 i 了,那么可以把这 i 个数字分成两个子列 {x}, {y} , 把这两个子列各自的和记为 X,Y 。那么有


可以得到 ,所以逐渐增加 i ,找到第一个满足这个公式的正整数X,此时 i 就是要求的值。

暂时想到这些,大牛们有没有更好的解法??

#搜狐##笔试题目##题解#
全部评论
用 i 步走到 target 数值,其实就是用 1,2,..,i 这 i 个数字,每个数字前面插入 + 号或 - 号,运算得到 target 。 1 到 i 到和是 (1+i)i/2 ,假设已经确定 i 了,那么可以把这 i 个数字分成两个子列 {x}, {y} , 把这两个子列各自的和记为 X,Y 。那么有 可以得到 ,所以逐渐增加 i ,找到第一个满足这个公式的正整数X,此时 i 就是要求的值。 我就接着这写了。为了简单起见,下面令t=target, 1)(必要条件,但不一定是充分条件)可以肯定的是对于给定的target,对应的所有可能的解一定满足: 由此,我们可以得到 因为Y必须是整数,所以由知,如果i是原问题的一个解,那么必须有: 且奇偶性相同。于是我们可以猜想:最优解就是满足上述条件的最小值。代码如下:int  int getStep(int N) {     int res=0;     int s=0;     while(s<N||s%2!=N%2)     {         ++res;         s+=res;     }    return res; } 下面给出上述结果的充分性证明。 2)(充分性)如果找到一个i使得由 确定的X,Y是整数,那么一定存在原问题的解,即存在集合的一个划分:,使得成立。其中P由取正号的数组成,N由取负号的数组成。 废话不多说。我们只要证满足的Y能表示成的一个子集所有元素和的形式。为此,我们将命题进行推广(至于为什么想到推广,完全来源于直觉以及以往的证明经验)得下面一个有趣的定理。 为了简单起见,我们用,其他开区间、闭区间类似。 定理1  , 有了这个定理,由,就可以证明上述的充分条件。下面是关于定理1的证明,有兴趣的可以看一下。 直白地说,就是从随便取出一些元素相加就可以得到0到之间的任何元素。我们举个例子如下:,则有 上面的例子按照特定的规则生成了所有1~10之间所有的数,至于0的生成取空集即可,即。 证明如下: 首先列举所有1个元素组成的和,得到区间, 然后列举2个元素组成的和,得到区间, 然后是3个元素的和,得到区间, ~~~~~ 最后是i个元素的和,得到区间 我们要证明两点 1)所有j个元素的和刚好组成一个区间 2)区间之间没有空隙。 首先证明区间没有空隙。 我们考虑相邻的两个区间 没有空隙等价于 , 这是很容易证明的。因为表示最大的由j个元素组成的和 所以如果j不等于i,那么一定有 , 两边加1,便可得到所要证明的结论。 为什么所有j个元素的和刚好组成一个区间呢?我们可以按照上面例子中的方法进行说明。 a)首先是最小的由j个元素组成的和,即,pos=j-1 b)如果V[pos]<V[pos+1]-1,下一个j个元素就是将V[pos]加1,否则就pos=pos-1,然后再V[pos]++。 知道pos<0为止。 在这个过程下一组数刚好是将前一组数中的某一个数加1得到,且始终保持V中元素是严格递增的(也就不会重复)。刚好可以列举出 之间所有的元素。 可以参考下面的伪代码 int pos=j-1; int V[]={1,2,3,....,j,i+1} while(pos!=-1) { for(int k=0;k<j;++k)cout<<V[k]<<" "; cout<<endl; if(V[pos]==V[pos+1]-1)--pos; ++V[pos]; } 至此,已经完成了定理1的证明。但是对于一个对数学的美有着特别追求的人,我还想到了另一个简单的基于数学归纳法的证明方法。 证明如下: 假设对于i命题已经成立,那么下面证明命题对i+1也成立。 对于i,最大的一个元素和是,接下来按照下面的顺序进行列举 上述列举保证了下一行比上一行刚好大1,一共有i+1列 所以可以一直列举到i+1时的最大元素. 这便证明了定理1. 我之前还想过一个问题,来源于找零钱的编程题。 问题如下:集合 包含了那些整数呢?上面所有的数都是整数,是给定的一些币值。 例如,给你币值为1,2,5的三种硬币,是不是能组合出所有的钱数呢? ~~~~~~ 是不是感觉所有的正整数都能凑出来!!! 再看一个例子 给定币值2、4,那么肯定凑不出3. 因为无论怎么凑,只能凑出个偶数来。 有兴趣的可以在好好想一想 结论是:存在一个足够到的N使得下面的结论成立: 即对于充分大的N,所求集合和最大公约数组成的集合相等。 说明:我也很菜,笔试的时候想着用广度优先去做,结果代码还没敲完时间就到了。只是心里一直放不下这个题,所以才写写感想。
点赞 回复 分享
发布于 2018-09-14 14:23
//66666,非常精髓了,我这么写的,也ac了 public static int getN(int n) {         if(n< 0) return getN(-n) ;         int i=0;         while(i*(i+1)<2*n){             i++;         }         if(i*(i+1)==2*n){             return i ;         }else{             if((i*(i+1)/2-n)%2==0){                 return i;             }else{                 if(i%2==0){                     return i+1 ;                 }                 else {                     return i+2 ;                 }             }         }     }
点赞 回复 分享
发布于 2018-09-13 21:02
所以你不回我微信就是在写这个???最终我还是没有被你从备胎池里捞起来
点赞 回复 分享
发布于 2018-09-13 20:59
😂😂😂尴尬,我还发帖了,大佬们都是这样做的啊。。我直接暴力了
点赞 回复 分享
发布于 2018-09-13 21:01
import sys try: def test(num,now,count): x=False temp=[] for i in now: if i+count==num or i-count==num: print(count) x= True break else: temp.append(i-count) temp.append(i+count) if x: return else: test(num,temp,count+1) while True: num = int(sys.stdin.readline().strip()) test(num,[0],1) except: pass
点赞 回复 分享
发布于 2018-09-13 21:29
不知道对不对
点赞 回复 分享
发布于 2018-09-13 21:30
还得解Y吧,同时保证Y为大于0的整数。反例:target=5,i=1,此时X=3,Y=-2
点赞 回复 分享
发布于 2018-09-13 21:54
你还不如让两个等式相减,然后得到2y=1(1+1)/2-target,就基本上得到大佬们的解题方法了。
点赞 回复 分享
发布于 2018-09-13 22:11

相关推荐

一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务