编译环境:c++
1、山寨金闪闪
描述:
金闪闪死后,红A拿到了王之财宝,里面有n个武器,长度各不相同。红A发现,拿其中三件武器首尾相接,组成一个三角形,进行召唤仪式,就可以召唤出一个山寨金闪闪。(例如,三件武器长度为10、15、20,可以召唤成功。若长度为10、11、30,首尾相接无法组成三角形,召唤失败。)红A于是开了一个金闪闪专卖店。他把王之财宝排成一排,每个客人会随机抽取到一个区间[l,r],客人可以选取区间里的三件武器进行召唤(客人都很聪慧,如果能找出来合适的武器,一定不会放过)。召唤结束后,客人要把武器原样放回去。m个客人光顾以后,红A害怕过多的金闪闪愉悦太多男人,于是找到了你,希望你帮他统计出有多少山寨金闪闪被召唤出来。
数据范围: 1≤n≤10^7 , 1≤m≤10^6 ,每件武器的长度满足 1≤val<2^32
算法思想:
首先声明数组,存储下输入的每件武器的长度。我们可以直到:对于给定的三个数,升序排列后,如果最小的两个数相加大于第三个数,那么一定可以构成三角形。所以要判断区间内是否能构成三角形召唤,那么可以对区间内的元素进行升序排列,三三一组来进行判断是否满足条件。
为了优化代码效率。因为每件武器的长度又在2^32方内,又可知,对于一个给定的升序序列,要想无法构成三角形,只能像斐波那契数列那样排列:1、1、2、3、5....。因为2^32-1=4294967295,在斐波那契数列的第47,48位2971215073,4807526976之间。所以有条件当区间大于46时不需要进行复杂的算法判断,一定会构成三角形(武器各不相同,所以1、2位的1舍去一个)。
代码部分实现:
2、电话号码分身
描述:
继MIUI8推出手机分身功能之后,MIUI9计划推出一个电话号码分身的功能:首先将电话号码中的每个数字加上8取个位,然后使用对应的大写字母代替 ("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"), 然后随机打乱这些字母,所生成的字符串即为电话号码对应的分身。
算法思想:
首先记录下输入字符串中各种字母的个数,用自动转化的ascii码作为字母的索引。要想从打乱的字符串中恢复出完整的数字字符串很难,所以我们可以观察每个数字字符特有的那些字符,首先,最容易区分的有五个分别是FOUR(U),SIX(X),TWO(W),EIGHT(G),ZERO(Z),可以根据这些特殊的字母的个数直接判断有多少个相应的数字;然后将他们所含的字母全部排除,然后其他具有重复字母的那些数字就有了特殊的字母,有FIVE(F),THREE(T);排除这些数字所含的字母个数后,又有SEVEN含有特殊的V,;最后剩下ONE(O),NINE(I)。
然后逆推回去+8之前的数字,比如现在4的个数对应的是原来电话号码中6的个数。然后将存储0-9数字个数的数组来顺序输出就可以得到最小的电话号组合。
代码部分实现:
3、末尾0的个数
描述:
输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2
算法思想:
0的末位其实就是5和偶数相乘得来的,那么我们可以分解n的阶乘所有的数,找到其中2和5的个数。又因为偶数的个数远远大于5的个数,所以我们可以直接考虑n的阶乘中可以分解出多少个5即可。n/5即为最接近n的整数的阶乘中含有5的个数,比如20/5=4,20中有5,10,15,20四个5的倍数。然后对结果继续递归调用,比如125的阶乘中含有25,25中又可以分解成2个5...打印结果即可
代码部分实现: