不同层次的程序员是如何解决问题的
本文仅供娱乐,切莫当真
感谢grant, liu, molly。 没有你们的帮忙我不可能完成这篇文章,谢谢大家
原题:5个水手在岛上发现一堆椰子, 夜晚睡觉后,第一名水手把椰子分为等量的5堆,还剩下一个给了猴子,自己藏起一堆。第二个水手把剩下的4堆混合后重新分为 等量的5堆,剩下一个给了猴子;自己藏起一堆。第三第四第五位水手依此办理。天亮以后,大家把剩下的椰子分为等量的5堆,剩下一个给了猴子。问原来这堆椰子最少为多少个。
for(i=0;i<=10000;i++){ check(i); }
printf("Please enter the number of pirates\n"); scanf("%d",&x); for(i=0;i<=1000000;i++){ check(i,x); }
#define NUM 5 //i是最后一次剩下的椰子个数 for(i=NUM-1;i<=INT_MAX;i+=NUM-1){ check(i,NUM); }
#define NUM_PIRATE 5 #define NUM_MONKEY 1 LARGEINT a,b,c,x,y; //from last pirate to first, recursively solve (n-1)x=ny+1 a=NUM_PIRATE-1; b=-NUM_PIRATE; c=NUM_MONKEY; for(i=0;i<NUM_PIRATES;i++){ //this function solves ax+by=c by extended-euclid algorithm extended_euclid(a, b, c, &x, &y); b=b*NUM_PIRATE; c=NUM_MONKEY+NUM_PIRATE*x; } return NUM_PIRATE*x+NUM_MONKEY;
数学家
他们不写程序,他们发现椰子的数量是下面这个方程的正整数解:
接着他们手算欧几里得算法来解这个方程
#define NUM_PIRATE 5 #define NUM_MONKEY 1 LARGEINT a,b,c,x,y; //这式子是不是很眼熟? a=pow(NUM_PIRATE-1,NUM_PIRATE); b=-pow(NUM_PIRATE,NUM_PIRATE+1); c=(-b-a*(NUM_PIRATE-1))*NUM_MONKEY; extended_euclid(a,b,c,&x,&y); return x;
echo 15621
P.S. 本文的代码简化了很多细节,譬如说求解ax+by=c的时候,欧几里得算法只应用于c=gcd(a,b)的情况,但本题中c=k*gcd(a,b)。而且,我们需要求的是最小正整数解,而不是任意一组解。还有一个就是LARGEINT必须实现高效率乘除法,这个细节就不在这里讨论了,呵呵
Some interesting C problems 2nd edition
总之就是很多很多关于C语言的问题啦。
本文稍稍有点长,点这里慢慢看吧
一道蛮有意思的面试题
本文写于2011-03-08
感谢mike,雪瑶姐,utd帮助我完成了这篇文章
题目:有n个数,其中绝大部分数出现了正好3次,只有一个数只出现了1次,请写一段程序把这个数找出来
解法1: 建一个hash table,把number作为key,遍历数组一遍,对出现过的数进行计数,最后再遍历一遍找到只出现一次的数。
空间复杂度:length(为了时间上高效,一般length要取到Theta(n))
时间复杂度: n^2/length+0.5n(n时间遍历一遍,每次要查找n/length的hash table,最后再遍历一遍)
解法2:对数组进行select,对小于pivot与大于pivot的数分别计数,对不能被3整除的一边进行递归调用。
空间复杂度:如果不在乎源数据被改变是可以仅用O(1)的空间的,但通常来讲需要O(n)空间来备份
时间复杂度:O(n)
解法3(感谢雪瑶姐提供):
public static int findSpecial(int[] array){
int ones = 0; //出现1次的1
int twos = 0; //出现2次的1
int not_threes; //出现3次的1取反
for(int i :array){
twos |= ones & i;
ones ^= i;
not_threes = ~(ones&twos);
ones &= not_threes;
twos &= not_threes;
}
return ones;
}
}
空间复杂度O(1),时间复杂度也是O(n),不会改变原数组,应该是最好的算法了
但是,这道题的讨论还没有完。假如把题目改成“有n个数,其中绝大部分数出现了正好2次,只有一个数出现了1次,请把这个数找出来” 有一个只需遍历一遍且不用额外空间的算法:把所有数字异或一遍,最后结果就是只出现1次的那个数。 那么,可能有人会想,在这道题的条件下,是不是也存在一个类似于异或的运算符#,可以仅把所有数#一遍以后就得到结果呢?、
答案是否定的。假如存在这个运算符#,那它必须满足下面这些条件:
A={所有32位2进制数} #:A->A
交换律 a#b=b#a
结合律 a#b#c=a#(b#c)
存在e 对于任意a a#e=a
对于任意a a#a#a=e
我们可以证明满足上面条件的运算符不存在:
首先我们定义一个负元-a:a#-a=e
由a#a#a=e 可知-a存在,根据结合律,-a=a#a (1)
假设-a不唯一,-a=b或c, 那么a#b#c=(a#b)#c=c=(a#c)#b=b(交换律&结合律)矛盾 (2)
由(1)(2)可知,-a存在且唯一。显然,-e=e
由交换律可知,如果a#b=e=>b#a=e,所以负元这个relation是可逆的, -a=b => -b=a
因为-e=e并且A是一个有限偶数项集合
所以必定还有一个数x,-x=x
那么x#x#x=e#x=x与题设里x#x#x=e矛盾
综上所述,这个运算符并不存在
感谢UTD同学在证明上的帮助
中关村在线伪造的下载地址分析
事情的起因是我偶然刷了一下页面,发现整个下载点的忙碌情况全变了
刷新前:
刷新后:
这变化课真够大,我稍微看了一下2个下载链接:
http://xiazai.zol.com.cn/down.php?softid=373274&subcatid=22&site=10c&server=10c0
http://xiazai.zol.com.cn/down.php?softid=373274&subcatid=22&site=10&server=101
就换了一个argument,完全是同一台服务器同一个页面(我估计也是同一个文件)……这忽悠一下外行人还行,咱程序员可不是那么好骗的
怀着不求甚解的态度,我又去查了一下它的页面生成代码:
var stat_arr=new Array('吉林网通下载','山西网通下载','河南网通下载','长春网通下载', '菏泽网通下载','承天网通下载','丽水网通下载','绵阳网通下载','茂名网通下载','大庆网通下载','昆明网通下载','天津网通下载' ); var pic_arr = new Array('a12.gif','a11.gif','a12.gif','a10.gif','a11.gif'); for (var i in stat_arr) { var num = Math.ceil(Math.random()*4); if(i%6==0){ document.write('</ul><ul>'); } if(i%2==0){ document.write('<li><img src="http://icon.zol-img.com.cn/soft/soft_new/'+ pic_arr[num]+'" /><a hr');document.write('ef="'+'/down.php?softid=373274&subcatid=22&site=10c&server=10c'+ i+'" nofollow>'+stat_arr[i]+'</a></li>'); }else{ document.write('<li><img src="http://icon.zol-img.com.cn/soft/soft_new/'+ pic_arr[num]+'" /><a hr');document.write('ef="'+'/down.php?softid=373274&subcatid=22&site=10&server=10'+i+ '" nofollow>'+stat_arr[i]+'</a></li>'); } }
好吧,随机生成图片+固定格式的伪造地址……这技术含量还可以再低点儿么,至少也给我配置一下dns服务器啊!!!
[真相]对不起,我们的专业不是万能的
本文写于2011-01-31
外人通常会对学计算机的人产生种种误解,在这里我给大家澄清一下:
1.你们能修电脑么?
对于广大使用windows的同学,我很遗憾的告诉你们,windows不是我写的,它也没有公开源代码,能让我知道它工作原理的途径很有限,我真的没有办法修。这就好比你在路上捡了一个阿拉丁神灯,在实现你1个愿望后突然坏了,你希望一个机械工程师能修好它,这可能么(我打赌就算是寓言家也不会修)?非要让我修,我也只能做3件事:杀毒google重装。要说计算机专业的比非专业的有什么优势,那就是google用的比较顺手把。
使用linux和mac的同学,有问题请自己解决。这是追寻自由的代价,同时也是你的义务,你的责任,当然你也可以把它看作是一种荣耀。
至于硬件问题么,请出门左转寻求电子系同学的帮助(大概电子系的同学也需要发篇这样的文章来澄清一下专业背景)
2.qq号被盗了能帮我拿回来么?
我不会说绝对不能,但这样做很难很难。大概就跟在公交车上被偷了钱包然后希望警察能抓住小偷一样难。所以,qq号被盗,请第一时间去腾讯官网寻求帮助,之后请自我反省为什么会被盗。
3.被问:嘿那你能当黑客么? 然后摇头说不能。 对方的眼神唰的一下就变成了鄙视。
其实我略懂一二……计算机专业也细分了很多方向,如果对方不懂安全知识(这里我不用“黑客”这个词,因为在程序员当中它的意义是神圣的),说明他只是个应用程序员,而不是系统级的程序员。
4.XXX软件你用过没? 答曰没用过。 对方吃惊:学计算机的你没用过XXX?
恩,没有用过,我都用自己写的XXXX <- just kidding. 学计算机的并不需要去使用那些乱七八槽的软件,一个文本编辑器就够了。即使要用,我们也倾向于使用开源软件而不是商业性质的非开源软件。
5. 帮忙挑一台电脑行么?
跟大家(特别是mm)普及一下科普知识:电脑和衣服鞋子化妆品是不同的,是不同的!一台电脑的性能好坏,数据说明了一切,没有什么感觉不感觉的。看不懂那些乱七八槽的参数不要紧,数字越大的就是越好的。如果还是弄不清楚,那越值钱的就是越好的。购买电脑的时候请先考虑自己能够承受多少价位的电脑,然后在这个价位里面选一个看着顺眼的就可以了。
顺便说一下,女生买电脑上网看电影用的,性能什么真的无所谓,只要是市面上还在卖的电脑做这些事情完全绰绰有余。男生买电脑打游戏用的,性能什么也无所谓,再高的配置也跑不动最新出的那些游戏,有买alienware的闲钱还不如去买台x360+tv。
另外,如果真的想知道多核的工作原理,ddr3和ddr2的区别,显卡为什么重要,rpm是什么意思,欢迎找我咨询——希望你面对一大堆专业术语不会觉得boring
一个安全的个人密码系统
本文写于2011-05-28
一早发现我的gmail有从异地登录的记录,这让我很震惊。我自认为是一个很有安全观的人,密码这种东西一向是小心处理的;同时我也是一个懒人,所有网站都用了同一个密码。虽然我很莫名,但我不得不承认,我的密码在某时某地以某种方式泄露了。这次密码泄露对我来说损失惨重,我不得不手动更新了其它主要网站的密码。
痛定思痛,我决定启用一种更加安全的密码机制。其能够达到以下几个目标:
1.能够用大脑轻松记住密码或密码的构造方式
2.不同网站不同密码
3.即使密码泄露,也只影响到被泄露的那个密码,而不会被推测出其它密码
4.即使知道我的密码构成方式,也不能破解我的密码
5.即使有人通过某种神通广大的方式获得了我的所有密码,他仍然不能破解我的密码
基本思路:one way hash, 单向散列加密,不清楚的朋友们可以参考一下wiki (http://en.wikipedia.org/wiki/Cryptographic_hash_function)。我们平常用的md5,sha256都是比较出名的hash算法。
简单说来,这种加密算法有2个特性:
1. one way单向:就是说你没有能力(这里我避免使用“不能”这个说法,如果有几千年的寿命应该可以吧,呵呵)去根据密文来破解明文,不管给你多少信息都不行
2. collision free冲突免疫:你没有办法构造2段明文来让它们的密文相同
这样,一旦我用hash加密了我的密码,然后把密文当做新密码的话,任何人都没有办法破解我的密码
具体方法:
工具: hash generator(网上随便下,千万别用在线版,你发出去的http请求可不会加密),字母表转换器(自己写)。通常hash函数是将一个字节流映射到另一个字节流的,我们必须把结果转化为能够从键盘输入的字符流。
方式:alphabet(hash(key, website)) 把网站名也hash进去就保证了每个网站密码不同
程序猿与爱情
本文写于2011-02-10
今天看到人人上好多朋友都在转载这个状态
程序猿 : zt:if ( you.Love(Me)==1 || you.Love(Me)==0 ) { love = love; love++; love--; } //你爱,或者不爱我,爱就在那里,不增不减
我都是24岁的老人了,本来我是懒得发表自己的爱情观人生观的,但是既然扯到程序了那我就来凑一脚。从programmer的角度来看,除了字面上的意思外,这段程序还可以引申出很多含义
if "you" equals to NULL, the whole program will crash. 你也许根本不了解你的爱人,你爱的他/她仅存在于你的幻觉之中,一旦你发现了真相,你的爱情将轻易崩溃
It seems that love returns an integer, but how do you know it only returns 0 or 1? It might range from -2^31 to 2^31-1! 你觉得这世上只有爱与不爱,但世事远比你想的复杂
love = love might be omiited while compiling. 你的豪言壮语海誓山盟,在别人眼中,或许什么都不是
love++; love--; If love is a global value, it will change in some situations, such as race condition . 不变的爱情是不存在的。你觉得不会变,仅仅是因为让你改变的事情没有发生罢了
换新博客了,吼一吼
最近在家呆得百无聊赖,便想重新开始写博客。 介于本人的老博客已经一年多没更新了,干脆重新开了一个。
没有看过我之前博客的朋友请不要担心,我会把我之前写的有价值的文章,重新编辑后发到这儿来(坦白说我真想要一个学中文的plmm帮我编辑啊^_^)。
在这个博客上,我不想介绍太多技术性的东西。我想要够通过一些互动性的文章,能够让人能觉得“写程序其实挺有趣的”。我也希望大家能够给我提供写作素材。
最后,感谢我的所有家人,朋友的支持。没有你们的支持我没法在自己喜欢的道路上走这么远。谢谢大家。