您的位置:首页 > 其它

数学计算

2015-06-27 12:17 274 查看
数学计算
计算小于n的素数个数

求总面积

统计数字的范围

判断是否是快乐数

有几个0尾巴

Excel列标题

数学计算

计算小于n的素数个数

# Ruby
# @param {Integer} n
# @return {Integer}
def count_primes(n)
return 0 if n <= 2
return 1 if n == 3
mark = [false] * n
t = Math.sqrt(n).to_i
counter = n - 2
for i in 2..t
next if mark[i]
(i * i).step n-1, i do |j|
next if mark[j]
mark[j] = true
counter -= 1
end
end
counter
end


Count Primes

求总面积



显然此题的关键是求相交部分的面积,可是两矩形的位置大小是任意的,相交与否,怎么相交,情况有多种,要考虑各种情况,感觉处理起来会比较费神。下面的解法唯一的特点就是逻辑极其简单:保持逻辑上的图形与题中例子的图片一致。

只需要保持长或宽方向上一致就行了: 求相交矩形的长的时候,保证h>d; 求相交矩形宽的时候,保证d>b。这么一来就把一个二维问题转化成了两个一维问题。思考起来就极简单。

# Ruby
def compute_area(a, b, c, d, e, f, g, h)
a, b, c, d, e, f, g, h = e, f, g, h, a, b, c, d if c > g
x = 0 if e >= c
x = c - e if e > a
x = c - a if e <= a
a, b, c, d, e, f, g, h = e, f, g, h, a, b, c, d if h > d
y = 0 if b >= h
y = h - b if b > f
y = h - f if b >= f
(c - a) * (d - b) + (g - e) * (h - f) - x * y
end


大神的解法:

// Java
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
int together;
if (C <= E || A >= G || B >= H || D <= F) {
together = 0;
} else {
int x = Math.min(C, G) - Math.max(A, E);
int y = Math.min(D, H) - Math.max(B, F);
together = x * y;
}
return (C - A) * (D - B) + (G - E) * (H - F) - together;
}


Rectangle Area

统计数字的范围

For example, given [0,1,2,4,5,7], return [“0->2”,”4->5”,”7”].

# Ruby
# @param {Integer[]} nums
# @return {String[]}
def summary_ranges(nums)
result = []
temp = []
nums.each do |num|
if temp.empty?
temp << num
else
if num - temp.last == 1
temp << num
else
if temp.count == 1
result << temp.pop.to_s
else
result << sprintf("%d->%d", temp.first, temp.last)
temp.clear
end
redo
end
end
end
result << temp.pop.to_s if temp.count == 1
result << sprintf("%d->%d", temp.first, temp.last) if temp.count > 1
result
end


牛人解法:

//C++
vector<string> summaryRanges(vector<int>& nums) {
int i = 0, size = nums.size();
vector<string> result;
while(i < size){
int j = 1;
while(i + j < size && nums[i + j] - nums[i] == j) ++j;
result.push_back(j <= 1 ? to_string(nums[i]) : to_string(nums[i]) + "->" + to_string(nums[i + j - 1]));
i += j;
}
return result;
}


Summary Ranges

判断是否是快乐数

Example: 如果n是快乐数, 那么用n各个数字的平方和代替n, 不断重复能使n=1。如果n不是快乐数,将是个无尽的循环。

如19是一个快乐数:

12+92=821^2 + 9^2 = 82

82+22=688^2 + 2^2 = 68

62+82=1006^2 + 8^2 = 100

12+02+02=11^2 + 0^2 + 0^2 = 1

Given : n是正整数

return:true 或 false

思路:判断是快乐数很简单,关键是判断不是快乐数并跳出循环。既然是循环,那应当会出现重复的n, 一旦新求得的n曾经出现过,便跳出循环。会不会出现n不重复且求不尽的情况呢?这个证明难住我了,留给别人去证明吧~

# Ruby
def is_happy(n)
array = []
until array.include? n
array << n
sum = 0
n.to_s.split('').each do |s| sum += s.to_i ** 2 end
return true if sum == 1
n = sum
end
false
end


其实还可以用哈希表(散列),若19是快乐数,那么82,68,100必然也是快乐数,若某数不是快乐数,那么那些计算过程中的中间值也必然不是快乐数,有点像求素数的方法。

Happy Number

有几个0尾巴

Given an integer n, return the number of trailing zeroes in n!.

即求整数n的阶乘的结尾有几个0。这种题最关键是弄清题意:

显然是问n!中因数10的个数,又n的因数2的个数肯定比因数5的个数多,只要有因数5就一定能找到因数2与其搭配成为10,那么因数10的个数就等于因数5的个数。接下来只需要注意时间复杂度就行了。

/* C */
int trailingZeroes(int n) {
int res = 0;
while(n){res += n /= 5;}
return res;
}


Factorial Trailing Zeroes

Excel列标题

For example:

1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB


/* C */
char* convertToTitle(int n) {
char *res = (char *)calloc(8, sizeof(char));
int i = 6;
while(n){
res[i--] = (char)((n-1) % 26) + 'A';
n = (n - 1) / 26;
}
return res+i+1;
}


挺像进制转换,但又不是直接转成26进制,有点像1-9,11-19,21-29…少了个位为0的数。就依这个例子简化问题,用n = (n - 1) / 9,恰能保持9进制,又能使9的倍数不进位。

Excel Sheet Column Title
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: