华为机试
1.求最小公倍数
正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
package main
import "fmt"
//辗转相除法求最大公约数
func gcd(A int,B int) int{
if(A < B){
t := A
A = B
B = t
}
if(A%B==0) {
return B
}else {
return gcd(B, A % B)
}
}
//如果可以相互整除,则返回较大的那个数;若不能相互整除,最小公倍数C=A*B/最大公约数
func main() {
var A, B int
fmt.Scanln(&A,&B)
if A > B && A % B ==0 {
fmt.Println(A)
}else if A < B && B % A ==0 {
fmt.Println(B)
}else {
fmt.Println(A*B/gcd(A,B))
}
}
2.求解立方根
计算一个数字的立方根,不使用库函数。
保留一位小数。
package main
import (
"fmt"
"math"
)
func taylor(n float64) float64 {
var x float64 = 1
var flag = true
for flag {
x = x - ((x*x*x - n) / (3*x*x))
if math.Abs(x*x*x - n) < 1e-8{
flag = false
}
}
return x
}
func main() {
var a float64
fmt.Scanln(&a)
fmt.Printf("%.1f",taylor(a))
}
3.最长上升子序列
Redraiment是走梅花桩的高手。Redraiment可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。他希望走的步数最多,你能替Redraiment研究他最多走的步数吗?
本题含有多组样例输入
输入
6
2 5 1 5 4 5
3
3 2 1
输出
3
1
package main
import (
"fmt"
)
func main() {
var n int
for{
num,err:=fmt.Scan(&n)//输入数组个数
if num==0||err!=nil{
return
}
nums := make([]int, n)//声明切片
for i := 0; i < n; i++ {//输入数组
fmt.Scanf("%d", &nums[i])
}
fmt.Printf("%d\n", dlc(nums))//输出结果
}
}
func dlc(nums []int) int {//输入:切片 输出:最长上升子序列的长度
max := 0
res := make([]int, len(nums))//为切片中的每个元素分配一个上升子序列的长度容器,初试值为1
for i := range nums {//49638 res 11111
res[i] = 1
}
for i, n := range nums {//外层循环,简单遍历切片,代表以每个元素为终点,寻找最长子序列
for j := 0; j < i; j++ {
if nums[j] < n && res[i] < res[j]+1 {//res0=1,4=4跳过;res1=1,4<9且1<1+1,res1=2,9=9,跳过,j=i跳出内循环
res[i] = res[j] + 1//......依次类推,得到限界最长子序列长度
}
}
if max < res[i] {//外循环中,内循环外,每执行完一次验证一下最大值
max = res[i]
}
}
return max
}
4.字符统计
输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。
本题含有多组样例输入
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
r := bufio.NewReader(os.Stdin)
for {//第一层循环,因为程序有多组输出
btys, _, _ := r.ReadLine()//btys是一个uint8类型的切片,实际上装载的就是字符对应的ASCII码
if len(btys) == 0 {
break
}
// 先将数据读入到此数组中
arr := make([]int, 256)//声明切片,长度为256(ASCII码的总个数),arr切片中存储的是每种字符的个数
for _, b := range btys {//遍历统计每个ASCII码出现的次数
arr[b]++
}
// 遍历数组,每次都找一个最大的值
for {//第二层循环,旨在按照次数多少排序,每次循环结束得到下一个应该出现的字符,且将其次数设置为0
max := 0
for j := 0; j < len(arr); j++ {//第三层循环,简单遍历,得到次数最多者,这里非常巧妙的是当 //两个字符次数相同时,由于j是从小到大遍历的,最后得到的一定是顺序较小的那个字符
if arr[j] == 0 {
continue
}
if arr[j] > arr[max] {
max = j
}
}
if arr[max] == 0 {
break//跳出第一层循环
}
arr[max] = 0
fmt.Printf("%c", max)
}
fmt.Println()
}
}