StackOverflow最近有一个面试题特别火爆:构造一个定义域和值域都是全体整数的函数f使得f(f(n)) = -n。如果你不能设计出函数对于所有n都成立,那就设计函数能够满足尽可能多的数。
一些比较容易想到的解如:
if n > 0:
return -n
else:
return n
不过这个函数只适用于所有非负整数。当然,这并不是我们的最优解。你还能想到更好的办法吗?
在思考这个问题时,我想到了一个奇妙的解:找一个非常非常大的素数p,然后定义函数f(n)为
if n % p == 0:
return - n / p
else:
return n * p
这个函数可以满足更多的数——只要n不含有因子p,函数总能使得f(f(n)) = -n。因此,取充分大的素数p,满足要求的整数可以任意多。
StackOverflow上的网友给出了下面这个答案,它对所有整数均成立:
if n == 0: return 0
if n >= 0:
if n % 2 == 1:
return n + 1
else:
return -1 * (n - 1)
else:
if n % 2 == 1:
return n - 1
else:
return -1 * (n + 1)
其实基本思想很简单:考虑四个数(a, b, -a, -b)。令f(a)=b, f(b)=-a, f(-a)=-b, f(-b)=a,则该函数对这四个数都满足要求。然后呢,只需要注意到函数对这四个数封闭,因此不断取(1, 2, -1, -2)、(3, 4, -3, -4)、(5, 6, -5, -6)……并对它们分别做类似的定义就可以了。
=================== 我是可爱的分割线 ===================
另一个类似的题目则是要求你设计函数f使得f(f(n)) = 1/n对所有实数都成立。解决办法也非常妙:
if n >= 0
return -1/x
else:
return -x
来源:http://techblog.zellux.czm.cn/2009/06/two-function-related-interview-questions/
沙发。。。。好感动
扩张的思想很NB
另,本月的UYHiP,m牛有没有研究?
抽象代数完全不理解。。。。。
f(n) = ni不行么?f(f(n)) = f(ni) = n * i *i = -n
这个解法在csdn上看到了,虽然对整数域是成立的,但是编程实现却反而不行:在一个int(或其他基本类型)的数字表达范围内,因为0的存在使得正数比负数少了一个。。。
够巧妙……
f(n) = ni
嘻嘻~~时隔很久都在同一天更新啦:)
f(n) = ni不行么?f(f(n)) = f(ni) = n * i *i = -n
问题是, ki属不属于整数集
这个时候,虚数i显得是多么的重要……
f(n)=i*n…….这个世界清静了……
哦,貌似楼上的都想到了……
我也想到了f(n) = n*i…………
没说清楚啊,我开始以为是数学函数来着……
另类解:
将n邪恶滴转化为字符串……
i其实不就是一个旋转吗,旋转不就是对应一个矩阵吗?这个函数根据这个思路就可以写出来吧
呵呵,很奇妙的题目,转了
if n >= p:
return 2*p-n
else:
return n-2*p
To starwing:
原文说清楚了啊,定义域和值域都是全体整数的函数f
有趣的题目,不过,除了这几种方法外还有吗?
http://www.cnblogs.com/skyiv/archive/2009/05/26/ffx.html
大素数的办法其实定义域和值域并不同,你利用了超出定义域范围很多的资源去存一个实际上很小的信息量.
http://yjq24.blogbus.com/logs/41051678.html
用建立[0,1]到(0,1)双射函数的办法可以构造R到R的f使ff(x)=-x
在StackOverflow上网友的那个答案的启发下,我觉得可以把那个答案扩展到实数域。只要在判断奇偶性时只针对整数部分就可以了。当然,对于(-1,1)中的值,还需要稍微处理下,比如>0时+2(<0时-2)就可类似做了。我是个懒人,具体函数式就不写了
f(n) = n * (-1)^n + (|n-1| – |n+1|)/2
建议查阅单墫《数学竞赛研究教程》第24讲
可以是 f(n) = i*n 吗。。i是虚数单位。。
。。。
感觉就是用某种方式在数里面存一个信息表示弄过一次了。。
能不能用xor之类的东西搞阿?
剛才推友才告訴我,這可能是國內第一篇文章討論這個問題。
我昨天寫了一篇 blog 關於這個問題:
http://www.cnblogs.com/miloyip/archive/2010/03/04/1677902.html
我測試的解,是不能滿足一個輸入(我的例子裡是INT_MAX)。沒測試過 stackoverflow 的解法,估計也有同樣的問題。
f(n)=n/2 当n是偶数
f(n)=-2n 当n是奇数
哦,楼上的错了。实际上我是想f(n)一次奇偶互变,再f(n)一次再换回来成相反数。这样就变回楼主贴子里贴的答案了,汗。。
这些函数也真够精妙的