接合时的长度L,当从标准输入提供N(1≤N≤5000)的条的长度时,通过连接N个条之间的三个长度的L,请写一个程序,以找到组合的总数。但是,和单个条的长度,长度拼凑在一起(L)是一个正整数,足够的处理范围在32位整数。另外,它的所有长度都与酒吧不同。
例如) 输入:
15
5
8
4
10
3
2
输出:
2 //{{2, 3, 10}, {3, 4, 8}}
示例2) 输入:
35
10
13
12
17
10
4
18
3
11
5
7
输出:
6 //{{4, 13, 18}, {5, 12, 18}, {5, 13, 17}, {7, 10, 18}, {7, 11, 17}, {10, 12, 13}}
我的回答在这里
package main
import (
"fmt"
"sort"
)
func main() {
input_count := 0
var target int
var count int
var v int
var array []int
for read_count, _ := fmt.Scan(&v); read_count != 0; read_count, _ = fmt.Scan(&v) {
if 0 == input_count {
target = v
} else if 1 == input_count {
count = v
array = make([]int, count)
} else {
array[input_count-2] = v
}
input_count++
}
sort.Ints(array)
fmt.Println(Calculate(target, count, array))
}
func Except(pair []int, count int, array []int) []int {
except := make([]int, count-pair[2])
except_index := 0
on := false
for _, v := range array {
if on {
except[except_index] = v
except_index++
}
if v == pair[1] {
on = true
}
}
return except
}
func ListUp(target int, count int, array []int) [][]int {
max := array[count-1]
list := make([][]int, Fact(count-1))
list_index := 0
for i, h := range array {
if count > i+1 && target > h+array[i+1] {
for j, v := range array[i+1:] {
if count > i+j+1 && target <= max+h+v && target > h+v {
list[list_index] = []int{h, v, i + j + 1}
list_index++
}
}
}
}
return list
}
//func Calculate(target int, count int, array []int) [][]int {
func Calculate(target int, count int, array []int) int {
// var answers [][]int
answer_count := 0
for _, pair := range ListUp(target, count, array) {
if 3 == len(pair) {
pair_sum := pair[0] + pair[1]
if target-pair_sum >= array[0] {
for _, v := range Except(pair, count, array) {
if target == pair[0]+pair[1]+v {
// answers = append(answers, []int{pair[0], pair[1], v})
answer_count++
}
}
}
}
}
return answer_count
}
func Fact(n int) int {
if n == 0 {
return 0
}
return n + Fact(n-1)
}
是否有人可以重构代码? 你应该重构它 如果输入 https://github.com/freddiefujiwara/horiemon-challenge-codeiq/blob/master/sample4.txt 然后输出
1571200
在10秒内
当前状态在这里
time ./horiemon-challenge-codeiq < sample4.txt
1571200
real 6m56.584s
user 6m56.132s
sys 0m1.578s
非常慢。
答案 0 :(得分:1)
你差不多七分钟的时间非常非常缓慢。十秒钟很慢。一秒钟更合理,十分之一秒是好的。例如,使用O(N * N)算法,
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
func triples(l int, b []int) int {
t := 0
sort.Ints(b)
// for i < j < k, b[i] <= b[j] <= b[k]
for i := 0; i < len(b)-2; i++ {
x := b[i]
if x > l {
break
}
lx := l - x
j, k := i+1, len(b)-1
y := b[j]
z := b[k]
for j < k {
yz := y + z
switch {
case lx > yz:
j++
y = b[j]
case lx < yz:
k--
z = b[k]
default:
// l == b[i]+b[j]+b[k]
t++
j++
k--
y = b[j]
z = b[k]
}
}
}
return t
}
func readInput() (l int, b []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
b = append(b, i)
}
if len(b) > 0 {
l = b[0]
b = b[1:]
if len(b) > 1 {
n := b[0]
b = b[1:]
if n != len(b) {
err := errors.New("Invalid number of bars: " + strconv.Itoa(len(b)))
return 0, nil, err
}
}
}
return l, b, nil
}
func main() {
l, b, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
t := triples(l, b)
fmt.Println(t)
}
输出:
1571200
real 0m0.164s
user 0m0.161s
sys 0m0.004s
为了比较,你的程序,
输出:
1571200
real 9m24.384s
user 16m14.592s
sys 0m19.129s
答案 1 :(得分:0)
我已经调整了
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
type triple struct {
x, y, z int
}
func triples(l int, n []int, list bool) (nt int, t []triple) {
num_of_list := len(n)
for i := 0; i < num_of_list-2; i++ {
x := n[i]
if x > l {
break
}
for j := i + 1; j < num_of_list-1; j++ {
y := x + n[j]
if y > l {
break
}
pos := sort.SearchInts(n[j:], l-y)
if j < pos+j && pos+j < num_of_list && n[pos+j] == l-y {
nt++
}
}
}
return nt, t
}
func readInput() (l int, n []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
n = append(n, i)
}
if len(n) > 0 {
l = n[0]
n = n[1:]
}
sort.Ints(n)
for i := 1; i < len(n); i++ {
if n[i] == n[i-1] {
copy(n[i:], n[i+1:])
n = n[:len(n)-1]
}
}
return l, n, nil
}
func main() {
l, n, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
list := false
nt, t := triples(l, n, list)
fmt.Println(nt)
if list {
fmt.Println(t)
}
}